mysql - 数据库设计——关系与属性

标签 mysql sql database database-design relational-database

我在设计数据库(SQL/MySQL)时遇到了问题。假设我们有一个用户,用户可以有很多 friend 和很多帖子,并填写了一些关于他自己的数据

很明显,对于friends,我们需要一个pivot_table 用于n:n 关系,对于posts,我们需要创建一个具有user_id (1:n) 关系的额外表.

所以我们需要usersuser_friendsposts 表。这是显而易见的。这才是处理关系的方式。

但现在假设我们希望用户拥有以下数据:

name - text
description - text
marital status - select only one from list
favourite colour - select only one from list
hobby - select up to 3 from list

对于文本字段(名称、描述),很明显我们只需在 users 表中创建 varchar/text 列即可。

一般问题是:应该如何处理其他字段(从列表中选择)?我应该为它们创建关系还是应该用它们创建标准数据列?

在我看来,没有必要为此创建关系表,因为使用列表(选择)我们只限制用户实际上可以粘贴到数据库中。理论上我们可以允许用户手动输入他喜欢的颜色作为他的颜色(例如 red 并且如果他输入错误的东西例如 reds 我们会比较它将会列出允许的 颜色)。性别也是如此——在我看来,当我们只容纳女人和男人并为其创建关系时,创建额外的表格是没有意义的。

第一个数据库设计:

例如,我可以为属性创建以下列:

marital_status - int
fav_colour - int
hobby_1 - int
hobby_2 - int
hobby_3 - int

还有另一个表(或者甚至是 PHP 或其他语言的普通数组),我在其中存储 fav_colour 的值 1 例如红色,爱好的值 2 是音乐等等(我如何存储并不重要这些值在这里 - 我也可以为此使用 enum 类型)。

对我来说,这种态度的好处不是创建许多实际上是属性而不是关系的关系(正如我上面提到的),因此工作量更少 + 更容易获取有关用户的信息 - 你不需要使用任何连接什么如果您有 20 或 100 个这样的属性,那将很重要,我可以很容易地在用户表中搜索。缺点也很明显 - 数据未标准化,对于任何多选(例如爱好)我需要创建 3 列,如果将来我决定用户不能选择 1 种颜色而是 2 或 3,我需要添加2 个额外的列。

替代数据库设计:

我创建了额外的表:colourshobbiesmarital_statuses 并且我创建了 3 个数据透视表:user_coloursuser_hobbiesuser_marital_statuses。缺点:许多连接。优点 - 如果我创建了 3 个额外的数据透视表,我可以轻松地允许用户选择多达 10 种颜色,而且我根本不需要重新设计数据库。但缺点也随之而来 - 搜索困难、工作量大、连接多。

详细问题

所以总结一下 - 假设哪种解决方案更好:

  1. 我可能不会更改一个属性的最大数量(如果我决定允许最多 3 个爱好,这可能永远不会改变)
  2. 许多字段的选择列表相对较短(大多数少于 10 个)
  3. 我需要在这样的数据库中进行大量搜索。例如,某人想要搜索将 fav_colour 设置为红色且有爱好音乐的用户。

如果您看到任何其他解决方案或优点/缺点,我很乐意与我分享。

最佳答案

听起来您想对您的某些用户属性实现一些约束。例如,最喜欢的颜色必须是红色、绿色、蓝色、粉色、橙色等之一;婚姻状况必须是单例、离婚、已婚之一。

您已经描述了一种方法:查找表。如果可能的值是动态的并且需要持续维护,或者如果有很多可能的值,这是最好的方法。从你的描述来看,那不是你的情况。您的可能值将是相当静态和简短的。

我建议使用 sql CHECK 约束。使用它,您可以控制字段的可能值。例如:

CREATE TABLE users
(
Name varchar(255) NOT NULL,
Description varchar(255),
Marital_Status varchar(10) NOT NULL,
Color varchar(10) NOT NULL,
CONSTRAINT chk_Color CHECK (Color in ('Red', 'Blue', 'Green', 'Orange')),
CONSTRAINT chk_Marriage CHECK (Marital_Status in ('Single', 'Married', 'Divorced'))
)

我没有对这个 DDL 语句进行语法检查,所以它可能包含标点符号错误。此外,语法可能因您的特定 DBMS 而异。我认为这应该适用于 MySQL。

关于mysql - 数据库设计——关系与属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26389176/

相关文章:

mysql - 选择特定日期输入的所有记录 - MySQL

sql查询以获取分布在按月分组的两个表中的两列的总和差

database - 如何处理 Web 应用程序中的并发更改?

database - 为什么我的 Django 批量数据库填充如此缓慢且经常失败?

database - NoSQL到底是什么?

MySQL 函数返回多行,需要 1 行

mysql - 为什么 MySQL 数据库中没有空闲空间?

php - CodeIgniter Active Record 删除特殊字符

java - 为什么在尝试对 ResultSet 中检索到的列的值求和时出现错误?

sql - 按时间顺序排列 Postgresql 表结果