什么是最好的MySQL表结构..或查询我现有结构的最佳方法?

时间:2011-12-08 06:06:39

标签: mysql database-design

我正在一个网站上工作,用户可以获得有关其个人资料(user_name,电子邮件,偏好等)的核心数据以及可能随时更改的任意数据。并非所有用户都需要所有数据字段。因此,在我的tblUsers MySQL表中,我不想添加一堆可能只对少数用户有用的列。

我想象的方法是创建第二个表,其中包含以下列: UID INT,dataType TINYINT,dataValue INT

基本上UID会指向users表中的用户ID(tlbUsers),而dataType会指向dataTypes列表(另一个表)中的ID,例如“Age”,“Favorite Color”,“Points”等等。

问题是,当我说: “SELECT * FROM tblUsers,tblData WHERE UID = ID” 我得到几排堆叠(效果很好......) 但我无法弄清楚如何编写一个考虑tblData信息的查询。

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

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

SELECT * FROM tblUsers, tblData, WHERE UID=ID AND dataAge = 21 AND dataScore >= 400 AND dataScore <= 500

但是,我不能这样做,因为dataAge和dataScore不是列 - 它们是dataTable中的行,如下所示:

    UID  dataType  dataValue
    35   1         21         //user #35's age (dataType 1)
    35   2         467        //user #35's score (dataType 2)
    49   1         21
    49   2         491

我无法预测将来需要哪些数据类型。 用户可以随意添加关于他们自己的数据类型,并非所有用户都会同时拥有所有可能的数据类型。

我想也可以使用另一个表,用于文本数据,格式相同,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

因为我想比较年龄和分数,所以dataType和dataValue在同一个调用中都会被模糊地使用...

我的问题:满足我需求的最佳表格结构是什么?如何正确查询我当前的设置?

1 个答案:

答案 0 :(得分:0)

用户必须满足查询中的所有条件,因此您必须多次加入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);

我认为idtblUsers的主键,并且会自动编入索引。

了解multi-column indexes in the manual

JOIN性能最近有所增加,但仍然缺乏其他数据库系统,如Oracle,SQL Server或PostgreSQL,其中JOIN处理非常高性能。 MySQL不是许多JOIN和子查询的最佳选择。

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