Mysql 棘手的数据库设计
我需要设计一个数据库来存储用户值:对于每个用户,都有一组特定的列 例如,Jon希望在一个包含两列的表中存储值:name、age Paul希望将值存储在一个3列的表中:水果、颜色、重量 在这一点上,我有两个选择 选项1-将数据存储为文本值 我会有第一个表“profiles”,其中包含用户的首选项:Mysql 棘手的数据库设计,mysql,sql,database,Mysql,Sql,Database,我需要设计一个数据库来存储用户值:对于每个用户,都有一组特定的列 例如,Jon希望在一个包含两列的表中存储值:name、age Paul希望将值存储在一个3列的表中:水果、颜色、重量 在这一点上,我有两个选择 选项1-将数据存储为文本值 我会有第一个表“profiles”,其中包含用户的首选项: +----+---------+--------+-------------+ | id | user_id | label | type | +----+---------+-----
+----+---------+--------+-------------+
| id | user_id | label | type |
+----+---------+--------+-------------+
| 1 | 1 | name | VARCHAR(50) |
| 2 | 1 | age | INT |
| 3 | 2 | fruit | VARCHAR(50) |
| 4 | 2 | color | VARCHAR(50) |
| 5 | 2 | weight | DOUBLE |
+----+---------+--------+-------------+
然后将数据作为文本存储在另一个表中:
+----+------------+--------+
| id | id_profile | value |
+----+------------+--------+
| 1 | 1 | Aron |
| 2 | 2 | 17 |
| 3 | 1 | Vince |
| 4 | 2 | 27 |
| 5 | 1 | Elena |
| 6 | 2 | 78 |
| 7 | 3 | Banana |
| 8 | 4 | Yellow |
| 9 | 5 | 124.8 |
+----+------------+--------+
之后,我将通过编程创建并填充一个干净的表
选项2-每种类型一列
在这个选项上,我会有第一个表“profiles2”,如下所示:
+----+---------+--------+------+
| id | user_id | label | type |
+----+---------+--------+------+
| 1 | 1 | name | 3 |
| 2 | 1 | age | 1 |
| 3 | 2 | fruit | 3 |
| 4 | 2 | color | 3 |
| 5 | 2 | weight | 2 |
+----+---------+--------+------+
+----+-------------+-----------+--------------+---------------+
| id | id_profile2 | int_value | double_value | varchar_value |
+----+-------------+-----------+--------------+---------------+
| 1 | 1 | NULL | NULL | Aron |
| 2 | 2 | 17 | NULL | NULL |
| 3 | 1 | NULL | NULL | Vince |
| 4 | 2 | 27 | NULL | NULL |
| 5 | 1 | NULL | NULL | Elena |
| 6 | 2 | 78 | NULL | NULL |
| 7 | 3 | NULL | NULL | Banana |
| 8 | 4 | NULL | NULL | Yellow |
| 9 | 5 | NULL | 124.8 | NULL |
+----+-------------+-----------+--------------+---------------+
与一组类型对应的类型:1=INT,2=DOUBLE,3=VARCHAR(50)
还有这样一个数据表:
+----+---------+--------+------+
| id | user_id | label | type |
+----+---------+--------+------+
| 1 | 1 | name | 3 |
| 2 | 1 | age | 1 |
| 3 | 2 | fruit | 3 |
| 4 | 2 | color | 3 |
| 5 | 2 | weight | 2 |
+----+---------+--------+------+
+----+-------------+-----------+--------------+---------------+
| id | id_profile2 | int_value | double_value | varchar_value |
+----+-------------+-----------+--------------+---------------+
| 1 | 1 | NULL | NULL | Aron |
| 2 | 2 | 17 | NULL | NULL |
| 3 | 1 | NULL | NULL | Vince |
| 4 | 2 | 27 | NULL | NULL |
| 5 | 1 | NULL | NULL | Elena |
| 6 | 2 | 78 | NULL | NULL |
| 7 | 3 | NULL | NULL | Banana |
| 8 | 4 | NULL | NULL | Yellow |
| 9 | 5 | NULL | 124.8 | NULL |
+----+-------------+-----------+--------------+---------------+
在这里,我有更干净的表,但仍然需要实现一个编程技巧,以使一切井然有序
问题
有人曾经面对过这种情况吗
你觉得我的两个选择怎么样
有没有更好的解决方案,不那么棘手
太多了
编辑
你好
我的模型有一个bug:无法检索“行”信息;i、 e.“值”表中的信息不可排序
在对EAV模型进行了一些修改之后,它显示出不适合,因为它不是为存储数据而设计的,而是为存储特定的信息而设计的
然后我以这个模型结束:
第一个表格“标签”:
+----+------------+------+----------+
| id | profile_id | name | datatype |
+----+------------+------+----------+
| 1 | 1 | 1 | Nom |
| 2 | 1 | 1 | Age |
| 3 | 2 | 2 | Fruit |
| 4 | 2 | 2 | Couleur |
| 5 | 2 | 2 | Poids |
+----+------------+------+----------+
然后是一个非常简单的“节点”,仅用于跟踪信息行:
+----+------------+
| id | profile_id |
+----+------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 2 |
+----+------------+
以及一组对应于不同数据类型的表:
+----+---------+----------+--------+
| id | node_id | label_id | value |
+----+---------+----------+--------+
| 1 | 1 | 1 | John |
| 2 | 2 | 1 | Doe |
| 3 | 3 | 3 | Orange |
| 4 | 3 | 4 | Orange |
| 5 | 4 | 3 | Banane |
| 6 | 4 | 4 | Jaune |
+----+---------+----------+--------+
有了这个模型,查询就可以了。数据输入有点棘手,但我会用干净的代码来处理
干杯看看。选项3:制作两张不同的桌子
一张桌子显然是给人的。另一个显然是水果。它们应该在不同的表中。为什么不只创建一个具有名称和ID的用户表,即一个具有键值对的userValues表呢?也就是说,约翰可以有关键的“水果”和“芒果”,还有另一个关键的“轮胎”和“固特异”。鲍勃可以有关键的“硬币”和价值的“便士”,关键的“年龄”和价值的“42”。任何人都可以有他们喜欢的任何价值,你有最大的灵活性。速度不会很快,你将不得不对价值施加限制,但这始终是一个权衡 干杯,
Daniel看这些问题示例,我的第一感觉也是EAV。Pro/Con-一个正确设计的EAV方案在理论上是无限可定制的;几乎所有的EAV实现都牺牲了RDBM服务器可以提供的任何/所有支持,将约束和完整性责任交给了应用程序。@David:通常EAV数据库中约束和数据完整性的责任落在每个临时用户的肩上。这并不漂亮。@David更不用说一个简单的查询,比如有多少香蕉的历史超过80年isEAV,让我想起了我看到的一个日常wtf,他们为在数据库中实现一个数据库而感到自豪。失去了参考价值完整性只有在你忘记了你试图执行的规则之前才是好的(如果你睡得太多,或者把项目交给另一个开发人员,那么这种情况就会发生。显而易见的解决方案是永远不要睡。)这个EAV是一个很好的关键字。它确实或多或少是我描述的选项1。性能和引用完整性的损失应该是无害的,因为我不必执行复杂的请求。是和否,这适合我的示例,但它不可扩展;我需要尽可能多的“表”“作为用户。我以前在其他问题中见过这种情况,但我永远无法得到明确的答案:为什么您需要每个用户都能够以这种方式输入自己的数据?对我来说,这表明设计中存在严重缺陷。模式应该规定用户可以存储哪些数据,而不是相反。我同意你的观点。但我必须建立一个模型,每个用户都可以定义自己的仪表板数据。Paul登录时说,“我想跟踪客户的姓名和年龄”;然后他输入数据。(以此类推,Peter想追踪他的羊的重量…)。嗨,你能解释一下选项1的区别吗?第二个表只有两列,键和值,所以完全通用。这真的是一个无限列的场景,还是一个固定的数字,比如50以下?无限规模的不同解决方案与花时间创建50列的人相比。