MySQL中的多值属性

时间:2017-12-07 12:23:34

标签: mysql data-structures database-design multivalue

我正在使用MySQL中的数据库来显示多值属性。我试图找到一种方法来创建父表和子表。我正在使用的想法是拥有员工桌和业余爱好桌。业余爱好者表中的爱好将被视为多值属性,因为员工可以拥有多个业余爱好。我的问题是,在创建这些表时,我应该使用3NF并添加一个3表来显示两者之间的关系,还是有一种方法可以用两个表来实现这个想法。我对多值属性不是很熟悉,所以我需要帮助创建表,只要每个键都使用哪种键,以及最终形式。我相信我需要以3NF的形式制作它并将业余爱好作为多值属性,但是将业余爱好表中的业余爱好者ID作为主键,将员工ID作为另一个主键,然后使关系表包含两者employee id和hobby id作为引用其他两个表的外键。任何有关显示多值属性的帮助或建议都将非常感谢!

2 个答案:

答案 0 :(得分:2)

您已经为员工准备了一张桌子。它可能有一个主键,我们会调用employee_id

你需要一张兴趣爱好的桌子。它需要一个主键,我们会调用hobby_id

然后,您需要一种方法来将员工和业余爱好与多对多联系起来。这是用第三个表格实现的,我们称之为employees_hobbies。使用这样的名称是一个好主意,因为下一个处理代码的人会立即认识到它的用途。

employees_hobbies应该有两列,employee_idhobby_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)

对于mysql来说,mva并不是很好。

并且存储它的最佳方式取决于您可以支付的价格和可访问性需求。如果你需要索引,因为数据库很大,而且负载很高,那么你可能需要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)

此方法的优点是查询较少, 缺点 - 可能比第一个慢。

当进口到狮身人面像时,高负荷系统也有优势......但这是另一个故事...