数据库设计:更多行与更多列?

时间:2017-04-21 15:05:48

标签: mysql

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

方法1:

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

id | uid | username | first_name | last_name | profession

OR

方法2:

表一:

id | uid | username 

表二:

uid | key | value |
1   | 'first_name' | John
2   | 'last_name'  | Donald and so on

第一种方法倾向于使用更多列来存储用户数据,而第二种方法依赖于多个表并将数据存储到每个用户的多个行中。

第二种方法意味着对于每个用户,user_meta表将具有大量行,而#1方法将更紧凑。

问题:

  1. 哪种方法在性能和查询速度方面更好?
  2. 是否有任何规则来设计数据库,您可以决定是否按行与列存储数据?

2 个答案:

答案 0 :(得分:1)

您实际上可以使用两者的组合。对于您可以定义的公共数据,请坚持使用具有固定列名称的表。 然后,当您添加(例如)客户定义的属性时,请使用第二种方法来补充数据。

答案 1 :(得分:1)

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

您提出的第二个模型通常称为" Entity-Attribute-Value"或EAV。您会找到详细的问题here

值得考虑的是这一点 - 想象一个屏幕,其中列出了今天登录的所有用户。在第一个模型中,您发出一个查询 - select * from users where last_logged_in >= '1 Jan 2015'

现在想象一下模型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'

两个外部联接,一旦超出这个简单的例子,就会出现一个复杂的查询。

如果您有大量其他数据,并且您不希望将其用作关系模型的主要部分(即将其用作连接或where语句中的条件),则可以使用MySQL& #39;支持JSONXML

这允许您存储在设计时可能不知道的模式的数据,以及哪些数据是"稀疏的" (即并非所有记录都填充了所有字段),但查询和填充到您的客户端语言稍微有点尴尬。