Mysql
 sql >> Database >  >> RDS >> Mysql

Relazione molti-a-molti SQL tra più tabelle

Sì, sembra tutto a posto. Ma...

Alcune note:

Utilizzeremmo un tipo di dati più breve per il gender colonna; Non vedo che avremmo bisogno di 255 caratteri per esprimerlo. (C'è un limite alla dimensione massima di una riga che viene applicata.) Se ci sono solo pochi valori per quello, considereremmo ENUM tipo di dati.

Probabilmente aggiungeremo anche NOT NULL vincoli su molte di queste colonne, come nome eroe, nome, cognome. Probabilmente aggiungeremo anche DEFAULT '' . A volte, abbiamo davvero bisogno di consentire valori NULL per qualche motivo, ma usiamo NOT NULL ovunque possiamo.

Sono titubante riguardo al TEXT colonne. Non c'è niente di sbagliato nell'usare TEXT tipo di dati, ma sono solo sospettoso che potrebbero "nascondere" alcune informazioni che potrebbero essere archiviate meglio in colonne aggiuntive.

Per le chiavi esterne, assegneremo un nome ai vincoli, seguendo lo schema che utilizziamo, e probabilmente aggiungeremo anche ON UPDATE CASCADE ON DELETE CASCADE

CONSTRAINT FK_superheroPower_power FOREIGN KEY (powerID) 
  REFERENCES power(id) ON UPDATE CASCADE ON DELETE CASCADE

Una nota sugli identificatori (nomi di tabelle e nomi di colonne)

Il modo in cui lo facciamo, tutti i nomi delle tabelle sono minuscolo . (Abbiamo un set di opzioni MySQL che forza tutti i nomi delle tabelle in minuscolo.) Lo facciamo per evitare problemi di incompatibilità per diversi sistemi operativi/filesystem (alcuni dei quali fanno distinzione tra maiuscole e minuscole e altri no).

Inoltre, i nomi delle tabelle sono singolari . Il nome della tabella indica ciò che una riga della tabella rappresenta. Inoltre non includiamo _table come parte del nome.

I nomi delle colonne in MySQL non fanno mai distinzione tra maiuscole e minuscole, ma usiamo sempre lettere minuscole anche per i nomi delle colonne. Non "camelCase" i nomi delle nostre colonne, utilizziamo il carattere di sottolineatura come separatori, ad es. power_id rispetto a powerID , hero_name rispetto a heroName .

SEGUITO

Le mie "note" sopra non sono regole specifiche che devono essere seguite; quelli sono solo modelli che usiamo.

Seguire questi schemi non garantisce che avremo un software di successo, ma ci aiuta.

Per riferimento, mostrerò come apparirebbero questi tavoli come un "primo taglio" dal nostro negozio, come illustrazione di un altro modello; questo è non "il modo giusto", è solo "un modo" su cui ci siamo stabiliti come squadra.

CREATE TABLE superhero
( id               INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'pk'
, hero_name        VARCHAR(255) NOT NULL                COMMENT ''
, first_name       VARCHAR(255) NOT NULL DEFAULT ''     COMMENT ''
, last_name        VARCHAR(255) NOT NULL DEFAULT ''     COMMENT ''
, first_appearance DATE                                 COMMENT 'date superhero first appeared'
, gender           ENUM('female','male','other')        COMMENT 'female,male or other'
, biography_text   TEXT                                 COMMENT ''
, universe         VARCHAR(255)                         COMMENT ''
, PRIMARY KEY(id)
, UNIQUE KEY superhero_UX1 (hero_name) 
) ENGINE=InnoDB;

CREATE TABLE power
( id               INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'pk'
, name             VARCHAR(255) NOT NULL                COMMENT ''  
, description_text TEXT NOT NULL                        COMMENT '' 
, PRIMARY KEY(id)
, UNIQUE KEY power_UX1 (name)
) ENGINE=InnoDB;

CREATE TABLE superheropower
( superhero_id   INT UNSIGNED NOT NULL         COMMENT 'pk, fk ref superhero'
, power_id       INT UNSIGNED NOT NULL         COMMENT 'pk, fk ref power'
, PRIMARY KEY(superhero_id, power_id)
, CONSTRAINT FK_superheropower_superhero 
     FOREIGN KEY(superhero_id) REFERENCES superhero(id)
     ON UPDATE CASCADE ON DELETE CASCADE
, CONSTRAINT FK_superheropower_power
     FOREIGN KEY (power_id) REFERENCES power(id) 
     ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB;