Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > it.comp.www.php > #22644 > unrolled thread
| Started by | ^Bart <gabriele1NOSPAM@hotmail.com> |
|---|---|
| First post | 2019-04-21 19:32 +0200 |
| Last post | 2019-04-22 19:13 +0200 |
| Articles | 5 — 2 participants |
Back to article view | Back to it.comp.www.php
[OT] MySQL/MariaDB db per gusti utenti ^Bart <gabriele1NOSPAM@hotmail.com> - 2019-04-21 19:32 +0200
Re: [OT] MySQL/MariaDB db per gusti utenti Alessandro Pellizzari <shuriken@amiran.it> - 2019-04-22 10:37 +0100
Re: [OT] MySQL/MariaDB db per gusti utenti ^Bart <gabriele1NOSPAM@hotmail.com> - 2019-04-22 18:01 +0200
Re: [OT] MySQL/MariaDB db per gusti utenti Alessandro Pellizzari <shuriken@amiran.it> - 2019-04-22 17:23 +0100
Re: [OT] MySQL/MariaDB db per gusti utenti ^Bart <gabriele1NOSPAM@hotmail.com> - 2019-04-22 19:13 +0200
| From | ^Bart <gabriele1NOSPAM@hotmail.com> |
|---|---|
| Date | 2019-04-21 19:32 +0200 |
| Subject | [OT] MySQL/MariaDB db per gusti utenti |
| Message-ID | <q9i9g9$1i7b$1@gioia.aioe.org> |
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
[toc] | [next] | [standalone]
| From | Alessandro Pellizzari <shuriken@amiran.it> |
|---|---|
| Date | 2019-04-22 10:37 +0100 |
| Message-ID | <gi5gahF2ut7U1@mid.individual.net> |
| In reply to | #22644 |
On 21/04/2019 18:32, ^Bart wrote: > A questo punto converrebbe gli ingredienti metterli tutti nello stesso > 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.
[toc] | [prev] | [next] | [standalone]
| From | ^Bart <gabriele1NOSPAM@hotmail.com> |
|---|---|
| Date | 2019-04-22 18:01 +0200 |
| Message-ID | <q9kohh$3g1$1@gioia.aioe.org> |
| In reply to | #22645 |
> In SQL hai relativamente poca scelta, una volta che decidi di > normalizzare i DB. Per ora ho studiato solo SQL, ho presente l'esistenza di altre tecnologie di cui però non conosco le caratteristiche, in base alla tua esperienza vi sarebbe ipoteticamente un'altra soluzione con un'altra tecnologia? > Quindi la tua seconda soluzione è quella giusta. E' sembrata anche a me la più "sensata" ed ho ragionato con la logica negativa (più sicura quando si parla di intolleranze) ovvero mettere nella tabella tutto ciò che è vietato stessa situazione per lo style. Ora ho un ultimo dubbio sulle traduzioni, ho una main table degli ingredients in inglese ed una ingredient_langs con tutte le traduzioni collegata ad ogni id della tabella ingredients. Ovviamente se ho un utente italiano leggerà dall'ingredient_langs gli id corrispondenti all'italiano ma un utente inglese dovrebbe leggere sempre dalla tabella ingredient_langs ma in realtà gli ingredienti con la sua lingua sono in ingredients! Morale della favola potrei copiare tutti gli ingredienti in inglese contenuti in ingredients pari pari in ingredient_lang ed assegnargli un id associato alla lingua inglese, non vedo altre soluzioni, di seguito un esempio: ingredients ------------------- id | name ------------------- 1 | milk 2 | spelt 3 | onion languages ------------------- id | name ------------------- 1 | english 2 | spanish 3 | italian ingredient_langs ---------------------------------------------------------- id | name |FK_id_languages|FK_id_ingredients ---------------------------------------------------------- 1 | Latte | 3 | 1 2 | Farro | 3 | 2 3 | Cipolla | 3 | 3 4 | Leche | 2 | 1 5 | Farro | 2 | 2 6 | Cebolla | 2 | 3 users ------------------------------------------------------------ id | name |FK_id_languages|FK_ingredient_langs ------------------------------------------------------------ 1 | John | 1 | ? 2 | Paolo | 3 | 1 3 | Paolo | 3 | 2 4 | Paolo | 3 | 3 5 | Firmin | 2 | 4 6 | Firmin | 2 | 5 7 | Firmin | 2 | 6 Ovviamente ho anche una tabella più specifica per gli users questa è solo di esempio per far capire il problema legato alla lingua inglese. > Bye. Saluti e grazie per la risposta! :) ^Bart
[toc] | [prev] | [next] | [standalone]
| From | Alessandro Pellizzari <shuriken@amiran.it> |
|---|---|
| Date | 2019-04-22 17:23 +0100 |
| Message-ID | <gi683eF802jU1@mid.individual.net> |
| In reply to | #22646 |
On 22/04/2019 17:01, ^Bart wrote: >> In SQL hai relativamente poca scelta, una volta che decidi di >> normalizzare i DB. > > Per ora ho studiato solo SQL, ho presente l'esistenza di altre > tecnologie di cui però non conosco le caratteristiche, in base alla tua > esperienza vi sarebbe ipoteticamente un'altra soluzione con un'altra > tecnologia? Ogni tecnologia ha i suoi pro e i suoi contro, e la stessa cosa può venire implementata con diversi tipi di DB con pro e contro. Bisognerebbe conoscere tutte le specifiche richieste dall'applicazione per consigliare qualcosa di specifico. La cosa migliore è sempre astrarre lo storage dalla logica dell'applicazione, e personalmente ho trovato che usare GraphQL a livello API porta a pensare a modi più astratti di strutturare il DB e renderlo indipendente, ma per ora ti consiglio di concentrarti su SQL e non pensarci troppo. > Ora ho un ultimo dubbio sulle traduzioni, ho una main table degli > ingredients in inglese ed una ingredient_langs con tutte le traduzioni > 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.
[toc] | [prev] | [next] | [standalone]
| From | ^Bart <gabriele1NOSPAM@hotmail.com> |
|---|---|
| Date | 2019-04-22 19:13 +0200 |
| Message-ID | <q9ksng$ml3$1@gioia.aioe.org> |
| In reply to | #22647 |
> renderlo indipendente, ma per ora ti consiglio di concentrarti su SQL e
> non pensarci troppo.
Credo anch'io sia la soluzione migliore!
> 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:
Ho capito il tipo di rogna... diciamo che basterebbe fare
"semplicemente" attenzione durante l'inserimento dei dati attenzione che
bisognerebbe porre anche se il collegamento fosse stato legato con una FK!
Però quando si dovessero aggiungere almeno una decina di lingue volendo
scegliere quella inglese come quella principale dovrei fare un filtro
specifico per tirarmi fuori tutti gli id ed associarli alle nuove lingue.
> 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):
Chiarissimo, da un'altra parte mi hanno suggerito, credo, la stessa
cosa; nell'esempio citato c'è un ingrediente milk che esiste in entrambe
le lingue mentre chi mi ha risposto ha supposto che ci potessero essere
due ingredienti senza traduzione in inglese come boter (butter) e eieren
(eggs).
Add a language_id to every table that has descriptions
so for Inredients:
ingredients
-------------------
id | language | name
-------------------
1 | 0 | milk
2 | 0 | spelt
3 | 0 | onion
Also define a 'default' language (i did choose to make '0' the default
language)
Other languages can be added (i.e. 1='Dutch')
1 | 1 | melk
4 | 1 | boter
5 | 1 | eieren
This can, of course, be 'beautified' with a foreign key, so you can only
create a dutch translation for an ingredient which has an English text.
SELECT ingredient.name
from ingredients, users
where id=3 and language_id = users.language_id
order by language_id desc
limit 1
This should give description in language of user, and when the
description in the language of the user does not exist it will show the
default ('0') description.
> Bye.
Saluti.
^Bart
[toc] | [prev] | [standalone]
Back to top | Article view | it.comp.www.php
csiph-web