Mysql 数据库设计:更多行还是更多列?

Mysql 数据库设计:更多行还是更多列?,mysql,Mysql,我正在开发一个应用程序,它需要我设计数据库。我想知道在以下情况下,什么是更优化的设计: 方法1: 有一个包含所有用户字段的用户表,即 id | uid | username | first_name | last_name | profession 或 方法2: 表一: id | uid | username 表二: uid | key | value | 1 | 'first_name' | John 2 | 'last_name' | Donald and so on 第一

我正在开发一个应用程序,它需要我设计数据库。我想知道在以下情况下,什么是更优化的设计:

方法1:

有一个包含所有用户字段的用户表,即

id | uid | username | first_name | last_name | profession

方法2:

表一:

id | uid | username 
表二:

uid | key | value |
1   | 'first_name' | John
2   | 'last_name'  | Donald and so on
第一种方法倾向于使用更多的列来存储用户数据,而第二种方法依赖于多个表并为每个用户将数据存储到多个行中

第二种方法意味着对于每个用户,user_元表将有大量的行,而方法1将更加紧凑

问题:

在查询的性能和速度方面,哪种方法更好? 在设计数据库时,是否有规则让您决定是否将数据存储在行还是列中?
实际上,您可以将两者结合使用。对于可以定义的公共数据,请坚持使用具有固定列名的表。
然后,当您添加例如客户定义的属性时,使用第二种方法补充数据。

您提出的第一种模型是常规关系设计。它被广泛使用,在速度和存储空间方面非常有效,但它要求您在存储数据之前了解数据模型;添加其他字段将需要更改架构

您提出的第二个模型通常称为或EAV。你会发现一个详细的问题

不过,这值得仔细考虑——想象一下,屏幕上列出了今天登录的所有用户。在您的第一个模型中,您发出一个查询-从上次登录的用户中选择*>='2015年1月1日'

现在想象一下模型2中的查询——您将得到如下结果

select u.*, ln.value, fn.value
from users u
outer join metadata ln on u.user_id = ln.user_id
and ln.key = 'last_name'
outer join metadata fn on u.user_id = fn.user_id
and fn.key = 'first_name'
and u.llast_logged_in >= '1 Jan 2015'
两个外部连接,以及一个复杂的查询(一旦您超出这个简单的示例)

如果您有大量的附加数据,并且不希望将其用作关系模型的主要部分,即在join或where语句中将其用作标准,那么您可以使用MySQL对or的支持


这允许您存储在设计时可能不知道其模式的数据,并且该数据是稀疏的,即并非所有记录都填充了所有字段,但查询并填充到客户机语言中会稍微有些尴尬

坚持使用第一种方法,只要您能够预测所需的属性。这对用户来说是正确的。如果表格是产品,而您无法预测某个产品的属性,则选择2。这被称为EAV模式btw。在任何情况下都不要使用第二个选项。EAV是一个性能杀手,只有在您无法预先定义所需的列时才应使用它来回答您的问题:1更快,2更灵活请参见我的产品示例,当不是每个条目都具有这样的属性时。第一种方法需要大量的空列,即cat上的NumberOfDoors,第二种方法只是没有用于该信息的行。数据库中的键值对存储几乎总是提供较差的性能。使用数据库规范化和非规范化来确定数据的结构。好的,但即使使用第一种方法,我也可以添加更多的列来容纳额外的信息。好吧,WordPress使用第二种方法将用户数据存储在其post_meta和user_meta表中。是的,第二种方法允许灵活性。但是我能不能在第一个数据库中添加额外的列来容纳更多的字段?对!我认为查询示例清楚地表明第一种方法更好。假设我必须为每个用户存储大量数据;但不要总是质疑它;方法1是否更可取?我已经编辑了答案。如果你问一些具体的问题而不是假设的场景,这会容易得多——一般来说,只使用列会更容易,即使它们不是全部填充的;如果有很多属性,或者您不知道它们的模式,那么可以使用文档存储XML或JSON。