1

I am working on a database in MySQL to show multivalued attributes. I am trying to find a way to create a parent and child table. The idea that I am working with is having an employee table and a hobby table. The hobbies in the hobby table would be considered the multivalued attributes since employees can have more than one hobby. My question would be, when creating these tables, should I use 3NF and add a 3 table to show the relation between the two or is there a way to implement this idea with simply two tables. I’m not very familiar with multivalued attributes so I need help creating the tables as far as what kind of keys each would use, as well as the end form. I believe I would need to make it in 3NF form and have the hobbies as the multivalued attribute, but have the hobby id from the hobby table as a primary key and the employee id as another primary key and then making the relational table contain both the employee id and hobby id as foreign keys referencing the other two tables. Any help or suggestions to show multivalued attributes would be greatly appreciated!

Justin
  • 21
  • 1
  • 6
  • sounds like you have to correct answer i.e. `employee`,`hobby`, & `employee_hobby` table. What are you stuck on? – Tom Mac Dec 07 '17 at 12:26
  • Mainly the keys when creating the table to ensure that I have everything implemented correctly. – Justin Dec 07 '17 at 12:38
  • A table for employees, a table for hobbies, both with an `id` column as primary key. A table relating employees and hobbies many-to-many, with two columns, `employee_id` and `hobby_id`. Those two columns together should be the composite primary key of the relating table. – O. Jones Dec 07 '17 at 12:40
  • This is a faq, what did you learn googling? What do you even mean by "multivalued attribute"? A relational/SQL table has one value per row/tuple per column/attribute. Many is not possible. So what are you trying to say? A non-relational design might have such a thing, but then you have to explain what such design you mean. Are you trying to say something about a column/attribute that is not functionally dependent on some column set in some relation/table? Are you trying to talk about MVDs? Explain what you mean instead of using a vague word willy-nilly. – philipxy Dec 09 '17 at 05:11
  • Possible duplicate of [SQL: multi valued attributes](https://stackoverflow.com/questions/8868395/sql-multi-valued-attributes) (among many others) – philipxy Dec 09 '17 at 05:14

2 Answers2

3

You have a table for employees already. It probably has a primary key we'll call employee_id.

You need a table for hobbies. It will need a primary key we'll call hobby_id.

Then, you need a way to relate employees and hobbies many-to-many. That's implemented with a third table, let's call it employees_hobbies. Using a name like that is a good idea, because the next guy to work on your code will recognize its purpose right away.

employees_hobbies should have two columns, employee_id and hobby_id. Those two columns together should be the composite primary key. Then, to confer a hobby on an employee, you add a row to employees_hobbies containing the two id values. If an employee drops a hobby, you delete the row.

If you want a list of employees showing their hobbies, you do this

 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

Use LEFT JOIN operations here to keep employees without any hobbies (all work and no play) in your list.

If you want to find the most common five hobbies and the employees doing them, try this

 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

This way of handling many-to-many relationships gives you all kinds of ways of slicing and dicing your data.

MySQL is made for this sort of thing and handles it very efficiently at small scale and large, opinions to the contrary notwithstanding.

(Avoid putting a surrogate primary id key into your employees_hobbies table. It adds no value.)

O. Jones
  • 103,626
  • 17
  • 118
  • 172
  • one quick question...when setting up the hobbies table, would each hobby_id have more than one hobby inside of it? For example would I set it up to look like....hobby_id = 1 (basketball, video games, exercising) or would each specific hobby have its own hobby_id? I was assuming each had their own ID. – Justin Dec 07 '17 at 20:27
  • One hobby per row in the `hobbies` table. Each hobby gets its own id. – O. Jones Dec 07 '17 at 22:38
-1

mva is not very good for mysql .

and best way to store it depend from price you can pay and accessibility need . if you need index , because database is big , and highly loaded , then possible you will need 2 tables .

employee( id , name )
employee_hobbies ( id , employeeid , hobbyid )

but in simplest case , or if you need good accessibility, you can just add text field to employee table , store there comma separated hobbyid , and then select by FIND_IN_SET() function .

e.q. single table

employee( id , name , MVA VARCHAR(512) )

you need be sure that all ids comma separated will fit into fields , side .

SELECT * from employee where FIND_IN_SET(some_hobbyid , MVA)

advantage of this method is less queries , disadvantage - may slower then 1st .

also there is advantages for high load system , when import into sphinx ... but this is another story ...

  • Downvoting for three reasons: 1) MVA works very well indeed in MySQL. 2) join tables should generally not have surrogate primary keys. 3) the denormalized, comma separated approach is truly an abomination for scalability. – O. Jones Dec 07 '17 at 12:59
  • scalability in mysql ? :-) – Alexey Yakovlev Dec 07 '17 at 13:12
  • O.Jones , I work with big data , and I know is it well or no , how many millisecond will take to query by MVA let say in mysql and sphinx . Every solution have it costs . Mysql is not good for MVA . Mysql have no native ways to index or select by MVA attributes . Sometimes better to have some abnormalization then write lot amount of code to support extra tables . Our life is not perfect . – Alexey Yakovlev Dec 07 '17 at 13:27
  • Just curious has anyone every heard of a plain join? Like I know about left and right, inner and outer joins but a friend was asking about a ‘regular’ or ‘plain’ join....I’m assuming that a regular join is just simply joining all entries from the two tables in question but they also said there’s a way to do a join of tables without using a join statement....is this a thing? – Justin Dec 07 '17 at 18:07
  • @Justin Do some research then post another question, don't ask in a comment. In SQL `join on` alone means `inner join on`. Comma/`.`is `cross join` with lower precedence than joins using "join". It is reasonable to consider `cross join` & `inner join` the same thing, with `on` the same as `where` but binding tighter. Go to some intros & the manual and learn the definitions of the expressions. [Read this](https://stackoverflow.com/a/25957600/3404097). – philipxy Dec 09 '17 at 05:04