我正在使用MySQL中的数据库来显示多值属性。我试图找到一种方法来创建父表和子表。我正在使用的想法是拥有员工桌和业余爱好桌。业余爱好者表中的爱好将被视为多值属性,因为员工可以拥有多个业余爱好。我的问题是,在创建这些表时,我应该使用3NF并添加一个3表来显示两者之间的关系,还是有一种方法可以用两个表来实现这个想法。我对多值属性不是很熟悉,所以我需要帮助创建表,只要每个键都使用哪种键,以及最终形式。我相信我需要以3NF的形式制作它并将业余爱好作为多值属性,但是将业余爱好表中的业余爱好者ID作为主键,将员工ID作为另一个主键,然后使关系表包含两者employee id和hobby id作为引用其他两个表的外键。任何有关显示多值属性的帮助或建议都将非常感谢!
答案 0 :(得分:2)
您已经为员工准备了一张桌子。它可能有一个主键,我们会调用employee_id
。
你需要一张兴趣爱好的桌子。它需要一个主键,我们会调用hobby_id
。
然后,您需要一种方法来将员工和业余爱好与多对多联系起来。这是用第三个表格实现的,我们称之为employees_hobbies
。使用这样的名称是一个好主意,因为下一个处理代码的人会立即认识到它的用途。
employees_hobbies
应该有两列,employee_id
和hobby_id
。这两列一起应该是复合主键。然后,为了给员工带来爱好,您需要向employees_hobbies
添加一行,其中包含两个id
值。如果员工放弃了业余爱好,则删除该行。
如果您想要一份显示其爱好的员工名单,请执行此操作
SELECT e.name, GROUP_CONCAT(h.hobbyname) hobbies
FROM employees e
LEFT JOIN employees_hobbies eh ON e.employee_id = eh.employee_id
LEFT JOIN hobbies h ON eh.hobby_id = h.hobby_id
GROUP BY e.employee_id, e.name
在此处使用LEFT JOIN
操作,让员工在您的列表中没有任何爱好(所有工作和不玩耍)。
如果您想找到最常见的五个爱好和员工,请尝试这个
SELECT COUNT(*) hobbycount, h.hobbyname,
GROUP_CONCAT(e.name ORDER BY e.name) people
FROM hobbies h
LEFT JOIN employees_hobbies eh ON h.hobby_id = eh.hobby_id
LEFT JOIN employees e ON eh.employee_id = e.employee_id
GROUP BY h.hobbyname
ORDER BY 1 DESC
LIMIT 5
这种处理多对多关系的方式为您提供了各种切片和切割数据的方法。
MySQL是针对这种事情而制作的,并且在小规模和大规模上非常有效地处理它,尽管如此,相反的意见。
(避免将代理主id
密钥放入您的employees_hobbies
表。它不会增加任何价值。)
答案 1 :(得分:-1)
并且存储它的最佳方式取决于您可以支付的价格和可访问性需求。如果你需要索引,因为数据库很大,而且负载很高,那么你可能需要2个表。
employee( id , name )
employee_hobbies ( id , employeeid , hobbyid )
但是在最简单的情况下,或者如果您需要良好的可访问性,您只需将文本字段添加到employee表,存储逗号分隔的hobbyid,然后通过FIND_IN_SET()函数选择。
如参见。单表
employee( id , name , MVA VARCHAR(512) )
你需要确保所有以逗号分隔的ID都适合于字段。
SELECT * from employee where FIND_IN_SET(some_hobbyid , MVA)
此方法的优点是查询较少, 缺点 - 可能比第一个慢。
当进口到狮身人面像时,高负荷系统也有优势......但这是另一个故事...