Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
最好的MySQL表结构是什么。。还是查询我现有结构的最佳方式?_Mysql_Database Design - Fatal编程技术网

最好的MySQL表结构是什么。。还是查询我现有结构的最佳方式?

最好的MySQL表结构是什么。。还是查询我现有结构的最佳方式?,mysql,database-design,Mysql,Database Design,我在一个网站上工作,在这个网站上,用户拥有关于他们个人资料的核心数据(用户名、电子邮件、首选项等)以及随时可能更改的任意数据。并非所有用户都需要所有数据字段。因此,在我的tblUsers MySQL表中,我不想添加一堆可能只对一小部分用户有用的列 我设想的方法是创建第二个表,其中包含以下列: UID INT,数据类型TINYINT,数据值INT 基本上,UID将指向用户表(tlbUsers)中的用户ID,数据类型将指向数据类型列表(另一个表)中的ID,如“年龄”、“最喜欢的颜色”、“点”等 问题

我在一个网站上工作,在这个网站上,用户拥有关于他们个人资料的核心数据(用户名、电子邮件、首选项等)以及随时可能更改的任意数据。并非所有用户都需要所有数据字段。因此,在我的tblUsers MySQL表中,我不想添加一堆可能只对一小部分用户有用的列

我设想的方法是创建第二个表,其中包含以下列: UID INT,数据类型TINYINT,数据值INT

基本上,UID将指向用户表(tlbUsers)中的用户ID,数据类型将指向数据类型列表(另一个表)中的ID,如“年龄”、“最喜欢的颜色”、“点”等

问题是,当我说: 从tblUsers、tblData中选择*其中UID=ID 我把几行放在一起(效果很好…) 但是我不知道如何编写一个将tblData信息考虑在内的查询

例如,假设我想选择所有21岁且得分在400-500之间的用户

如果它们是实际列,我会说:

SELECT * FROM tblUsers, tblData, WHERE UID=ID AND dataAge = 21 AND dataScore >= 400 AND dataScore <= 500
我无法预测将来需要什么数据类型。 用户可以任意添加关于自己的数据类型,并且不是所有用户都可以同时拥有所有可能的数据类型

我设想还使用另一个表,用于文本数据,格式相同,UID,dataType,dataString

让我们假设我写作

SELECT * FROM tblUsers, tlbData, WHERE UID=ID AND dataType=1 AND dataValue=21 AND dataType=2 AND dataValue >= 400 AND dataValue <= 500

SELECT*FROM tblUsers,tlbData,其中UID=ID,dataType=1,dataValue=21,dataType=2,dataValue>=400,dataValue用户必须满足查询中的所有条件,因此您必须多次加入
tblData
,就像它是多个表一样:

SELECT u.*
FROM   tblUsers u
JOIN   tblData d1 ON d1.uid = u.id AND d1.dataType=1 AND d1.dataValue=21
JOIN   tblData d2 ON d2.uid = u.id AND d2.dataType=2
                                   AND d2.dataValue BETWEEEN 400 AND 500

对评论中补充问题的回答 要实现这一点,索引至关重要。在特定情况下,您可能需要以下索引:

CREATE INDEX tbldata_uid_idx ON tblData(uid);
CREATE INDEX tbldata_datatype_datavalue_idx ON tblData(dataType, dataValue);
我假设
id
tblUsers
的主键,并自动编制索引

了解

联接性能最近有所提高,但仍落后于其他数据库系统,如Oracle、SQL Server或PostgreSQL,在这些系统中联接的处理效率非常高。MySQL不是很多连接和子查询的最佳选择


对于您的特定情况(可以组合多个连接),位图索引扫描将提供最高性能—这是MySQL中不存在的功能。它有一个“索引合并”功能,所以可以替代它。

完美!非常感谢你。。。我从未意识到您可以在一行中对同一个表进行多个联接!嗯,现在我开始怀疑性能和可伸缩性。假设平均用户有20个额外的数据点需要检查。TLB数据中的每一行对应20行。TLB数据将继续像这样线性增长。要查询,这将需要一行20个连接,而这似乎。。。慢?假设数据库增长到1GB,那会是20GB的通行证吗?或者缓存查询结果是否足够智能。。。还是一次就完成了?Hmmm.@guypwood:关键元素是索引。对于许多具有大表的连接和子查询,mysql可能不是最佳选择,但它肯定可以完成这项工作。我在上面的回答中添加了一个额外的答案。啊,再次感谢你让我走上正确的道路!现在我将使用MySQL多索引,但我真的很感激您尽可能列出位图索引和其他可用技术,以防我需要交换MySQL。。。好东西!
CREATE INDEX tbldata_uid_idx ON tblData(uid);
CREATE INDEX tbldata_datatype_datavalue_idx ON tblData(dataType, dataValue);