【问题标题】:join with multiple foreign keys加入多个外键
【发布时间】:2014-11-08 08:43:32
【问题描述】:

我有一个 tbl_categories 表如下:

id  category_name   parent_id   status  category_order  slug 

我有另一个表 tbl_users,其中每个用户记录最多可以属于每个主类别中的 3 个主要类别和 3 个子类别(因此,总共 3 个主要类别和 9 个子类别)

我知道我可以在 tbl_users 表上使用别名并创建我的查询,该查询将返回用户所属的类别和子类别。但是,我可以为 tbl_users 表想到的表结构如下所示:

id 用户名密码 maincat_1 subcat_1_1 subcat_1_2 subcat_1_3 maincat_2 subcat_2_1 subcat_2_2 subcat_2_3 maincat_3 maincat_3_1 maincat_3_2 maincat_3_3

有没有更好的结构/方式来做到这一点?

【问题讨论】:

  • 结构不错。您可以创建一个将猫与用户联系起来的表,但是您将有一个更复杂的连接查询,而且必须在某处的代码中强制执行 3/9 规则。

标签: mysql sql database database-schema


【解决方案1】:

有更好的办法:

tbl_categories 的结构很好。

添加另一个存储用户数据的结构:

id username password 

每个用户将在此处存储一次。然后添加一个“数据透视表”或翻译表USERS_CATEGORIES 来连接您的usercategories 表:

userID categoryID

每个用户都可以在这里存储不止一次,例如三个主要类别存储三次。

如果您想获取用户所在的所有类别名称,您可以执行如下查询:

SELECT tbl_categories.category_name
FROM tbl_categories, USERS_CATEGORIES, USERS
WHERE USERS.username = 'My Name'
AND USERS.id = USERS_CATEGORIES.userID
AND USERS_CATEGORIES.categoryID = tbl_categories.id

理论背景称为“数据库规范化”——见here

【讨论】:

  • 你忘了限制,每个用户必须在 3 个或更少的类别和 3 个或更少的子类别中
  • 不,我在USERS_CATEGORIES 中有这个。您可以为不同的类别多次添加相同的用户 ID。要区分主类别和子类别,您可以在 USERS_CATEGORIES 中添加一些标志,例如
  • @Benni 我在问题中建议的方式需要在存在用户信息的同一个表中插入类别。这意味着当用户提交表单时,他/她的详细信息 + 类别详细信息仅存储在一张表中的一次插入操作中。为一个用户可能有 12 条记录 (3 + 9) 的类别创建不同的表的动机是什么?
  • @Benni 的答案是正确的方法。对数据库的查询将更加简单、规范化并且更容易使用索引。
【解决方案2】:

查询属于用户的子类别:

SELECT t1.first_name, t1.last_name, m1.category_name AS maincategory_1, m2.category_name AS maincategory_2, m3.category_name AS maincategory_3
    FROM tbl_user_individual AS t1
    LEFT JOIN tbl_categories AS m1 ON t1.subcat_1 = m1.id
    LEFT JOIN tbl_categories AS m2 ON t1.subcat_2 = m2.id
    LEFT JOIN tbl_categories AS m3 ON t1.subcat_3 = m3.id
    LEFT JOIN tbl_categories AS m4 ON t1.subcat_4 = m4.id
    LEFT JOIN tbl_categories AS m5 ON t1.subcat_5 = m5.id
    LEFT JOIN tbl_categories AS m6 ON t1.subcat_6 = m6.id
    LEFT JOIN tbl_categories AS m7 ON t1.subcat_7 = m7.id
    LEFT JOIN tbl_categories AS m8 ON t1.subcat_8 = m8.id
    LEFT JOIN tbl_categories AS m9 ON t1.subcat_9 = m9.id
    WHERE 
    m1.slug = 'english_1394435671' OR
    m2.slug = 'english_1394435671' OR
    m3.slug = 'english_1394435671' OR
    m4.slug = 'english_1394435671' OR
    m5.slug = 'english_1394435671' OR
    m6.slug = 'english_1394435671' OR
    m7.slug = 'english_1394435671' OR
    m8.slug = 'english_1394435671' OR
    m9.slug = 'english_1394435671'

要知道用户是否属于主要类别,查询会更短,因为用户只能属于 3 个主要类别。 希望这对某人有帮助!

【讨论】:

    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 2016-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-25
    • 2010-10-15
    • 2010-09-05
    相关资源
    最近更新 更多