Newsgroup: it.comp.www.php
Titolo: [OT] MySQL/MariaDB db per gusti utenti

Salve,
 
dovrei creare un db per raccogliere i gusti degli utenti, nello 
specifico mi trovo in questa situazione:
 
CREATE TABLE foodstyles
(
id_foodstyle BIGINT(7) NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL UNIQUE,
FK_id_ingredient SMALLINT(7) NOT NULL,
PRIMARY KEY (id_foodstyle),
INDEX (FK_id_ingredient),
FOREIGN KEY (FK_id_ingredient) REFERENCES ingredients (id_ingredient)
)
ENGINE=INNODB;
 
In questo caso dovrei ripetere vegan tutte le volte necessarie a 
raccogliere tutti gli ingredienti che formano il gruppo vegan:
 
name   | FK_id_ingredient
vegan  |       4
vegan  |       2
vegan  |       8
vegan  |       9
vegan  |       3
 
A questo punto converrebbe gli ingredienti metterli tutti nello stesso 
campo evitando quindi la FK?
 
Ho pensato anche di creare una tabella con tutti gli stili quindi vegan, 
vegetarian ed avere una tabella tipo:
 
FK_food   | FK_id_ingredient
1         |       4
1         |       2
1         |       8
1         |       9
1         |       3
 
Ma credo cambi poco...
 
Saluti!
^Bart

 campo evitando quindi la FK?
 
In SQL hai relativamente poca scelta, una volta che decidi di
normalizzare i DB.
 
1:1 -> Metti tutto nella stessa tabella
 
1:n -> Hai una tabella con gli "1", e una tabella con gli "n".
 
n:m -> Hai 3 tabelle: una con gli "n", una con gli "m" e una con solo
due colonne: fk_n e fk_m
 
Nel tuo caso hai una relazione n:m
Un ingrediente può appartenere a diversi stili.
Per esempio, il latte è vegetariano e onnivoro, ma non vegano, mentre il
radicchio appartiene a tutti e tre, ma non al carnivoro.
 
Quindi la soluzione è una tabella con gli stili, una con gli ingredienti
e una tabella di link:
 
create table foodstyle (
  id int not null auto_increment primary key,
  name varchar(255)
)
 
create table ingredient (
  id int not null auto_increment primary key,
  name varchar(255),
)
 
create table foodstyle_ingredient (
  foodstyle int not null,
  ingredient int not null,
  foreign key fk_foodstyle(foodstyle) references foodstyle (id),
  foreign key fk_ingredient(ingredient) references ingredient (id)
)
 
Quindi la tua seconda soluzione è quella giusta.
 
Bye.
 

 Bye.
 
Saluti e grazie per la risposta! :)
^Bart
 

 collegata ad ogni id della tabella ingredients.
 
Io lo farei in modo leggermente diverso: una singola tabella per gli
ingredienti, con una chiave primaria su due colonne:
 
create table languages (
  id primary key -- bla bla bla la roba di MySQL
  name varchar(255)
)
 
create table ingredients (
  id int, -- NB: no primary key
  lang int,
  name
  foreign key fk_lang(lang) references languages(id),
  primary key (id, lang)
)
 
Hai la rogna di dover generare a mano un nuovo "id" quando crei un nuovo
ingrediente, ma la tabella diventa qualcosa tipo:
 
--------------------------------
id	|     name	| lang |
--------------------------------
1	|     Latte	|   3  |
2	|     Farro     |   3  |
3	|     Cipolla	|   3  |
1	|     Leche	|   2  |
2	|     Farro	|   2  |
3	|     Cebolla	|   2  |
 
Quindi il latte avrà sempre id 1 in tutte le lingue, e costruire le
query sarà più semplice, oltre a non dover avere un'asplosione algebrica
di righe nella tabella users (ricorda che è n:m, quindi ti serve una
tabella di collegamento):
 
create table users(
  id primary key,
  name varchar(255)
)
 
create table user_ingredients (
  user int,
  ingredient int,
  foreign key fk_user(user) references users(id),
  foreign key fk_ingredient(ingredient) references ingredients(id)
)
 
Per esempio, volendo prendere gli ingredienti dell'utente 5 in spagnolo
(lang 2):
 
select 
u.id
, 
u.name
, 
i.name
 
from
  users u
left join user_ingredients ui
  on ui.user = 
user.id
 
left join ingredients i
  on 
i.id
 = ui.ingredient
  and i.lang = 2
where
 
u.id
 = 5
 
O qualcosa del genere (non l'ho testata)
 
Bye.

 Bye.
 
Saluti.
^Bart