【问题标题】:Database Design: dating-site-like application?数据库设计:类似约会网站的应用程序?
【发布时间】:2011-09-22 18:46:52
【问题描述】:

假设一个类似约会网站的网络应用程序,其中每个配置文件都可以有一个或多个用户。例如,每个用户都有以下列:姓名、年龄、性别。

我认为数据库设计如下:

TABLE profile
=============================
| profile_id | name         |
=============================
| 1          | Dynamic Duo  |
-----------------------------

TABLE user
================================================
| user_id | profile_id | name   | age | gender |
================================================
| 1       | 1          | Batman | 35  | Male   |
------------------------------------------------
| 2       | 1          | Robin  | 25  | Male   |
------------------------------------------------

数据库设计好不好?我将如何查询以下内容:

  • 查找用户的性别=男性的所有个人资料
  • 查找用户性别为男性和女性的所有个人资料
  • 查找用户性别为男性和女性且每个用户的年龄为 > 20 且
  • 查找关联用户超过 2 个的所有个人资料

如果数据库设计不能支持这样的查询,那会是什么设计?

【问题讨论】:

  • 那些“我将如何查询”的问题非常基础。在我看来,你可能已经在你的头上。 (这是一种观察,而不是批评。)

标签: mysql database database-design relational-database normalization


【解决方案1】:

我给了性别属性位的类型。

第一个是;

-- All male
SELECT * FROM profiles p
  WHERE p.id NOT IN
    (SELECT u.profile_id FROM users u WHERE u.gender != 1);

第二个;

-- Male and female
SELECT * FROM profiles p
  WHERE p.id IN
    (SELECT u.profile_id FROM users u WHERE u.gender = 1)
    AND p.Id IN
    (SELECT u.profile_id FROM users u WHERE u.gender = 0)

第三个类似,只需在两个子查询中添加AND u.age > 20 AND u.age < 40即可。

第四;

-- Number of associated users above 2
SELECT *, count(p.id) AS user_count FROM profiles p
  JOIN users u ON p.id = u.profile_id
  GROUP BY p.id HAVING count(u.id) > 2

【讨论】:

  • 我会测试您的查询。他们看起来很有希望。不过,您认为数据库设计正朝着正确的方向发展吗?仅仅因为它可以被查询并不意味着它是好的设计。
  • 您显示的两个表看起来不错。请注意,我的查询并未针对性能进行优化。对您的用户表不利的一件事是,您需要过滤一个非常非唯一的性别字段。这使得 MySQL 通常必须评估所有行,因为索引可能效率低下。但是使用 bit 类型会比 varchar 高效得多。
  • 对于gender,我正在考虑使用 ENUM(有 3 种性别,第 3 种是跨性别)。我担心您的陈述“您需要过滤一个非常非唯一的性别字段”,因为我不完全理解您的意思。肯定会比这些查询更多(例如,特定用户可能拥有的“兴趣”列表并尝试将此类用户与具有相似兴趣的其他用户匹配)。我会头疼吗?
  • 快速查询的一般经验法则是过滤不太可能与许多行共享其值的字段。例如,如果您的 users 表中有 100 000 行,其中一半是男性,则查询 gender=male 无论如何都必须返回一半的行 - 所以根据 dbms,它可能不使用性别索引,因为它将不得不进行如此多的查找,因此最好进行全索引扫描。你不应该太担心这一点,因为除非你期待大量的数据。同样对于昂贵的查询,总是有 mysql 或 memcache 缓存的选项。
猜你喜欢
  • 2010-12-19
  • 2021-05-26
  • 1970-01-01
  • 1970-01-01
  • 2014-02-07
  • 2013-12-31
  • 1970-01-01
  • 2016-10-19
  • 1970-01-01
相关资源
最近更新 更多