Come creare relazioni in MySQL


96

In classe, stiamo tutti "studiando" database e tutti usano Access. Annoiato da questo, sto cercando di fare quello che fa il resto della classe, ma con comandi SQL non elaborati con MySQL invece di utilizzare Access.

Sono riuscito a creare database e tabelle, ma ora come faccio a creare una relazione tra due tabelle?

Se ho le mie due tabelle come questa:

CREATE TABLE accounts(
    account_id INT NOT NULL AUTO_INCREMENT,
    customer_id INT( 4 ) NOT NULL ,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
    PRIMARY KEY ( account_id )
)

e

CREATE TABLE customers(
    customer_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    address VARCHAR(20) NOT NULL,
    city VARCHAR(20) NOT NULL,
    state VARCHAR(20) NOT NULL,
    PRIMARY KEY ( customer_id )
)

Come creo una "relazione" tra le due tabelle? Voglio che a ogni account venga "assegnato" un customer_id (per indicare chi lo possiede).


48
"MI RIFIUTO di studiare Access, studierò un VERO motore di database: MySQL" Questo è lo spirito! Congratulazioni = D
Metafaniel

2
Si noti che i vincoli di chiave esterna non implementano le relazioni, ma implementano l'integrità. L'associazione tra account_id e customer_id nella tabella account implementa la relazione tra le rispettive entità.
Reaanb

1
"Questo è lo spirito!", Purché sia ​​mysql con InnoDB, non MyISAM. Inoltre postgreqsl ha alcune caratteristiche interessanti su MySQL che vale la pena guardare.
jgmjgm

Risposte:


102

Se le tabelle sono innodb puoi crearlo in questo modo:

CREATE TABLE accounts(
    account_id INT NOT NULL AUTO_INCREMENT,
    customer_id INT( 4 ) NOT NULL ,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
    PRIMARY KEY ( account_id ), 
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 
) ENGINE=INNODB;

Devi specificare che le tabelle sono innodb perché il motore myisam non supporta la chiave esterna. Guarda qui per maggiori informazioni.


Ho visto in un articolo che non è necessario specificare la clausola ENGINE = InnoDB se InnoDB è definito come motore di archiviazione predefinito, è possibile verificare utilizzando il comando (mysql> SELECT @@ default_storage_engine;)
Arun

80

come ha detto ehogue, mettilo nel tuo CREATE TABLE

FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 

in alternativa, se hai già la tabella creata, usa un comando ALTER TABLE:

ALTER TABLE `accounts`
  ADD CONSTRAINT `FK_myKey` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`customer_id`) ON DELETE CASCADE ON UPDATE CASCADE;

Un buon modo per iniziare ad imparare questi comandi è usare gli strumenti della GUI di MySQL , che ti danno un'interfaccia più "visiva" per lavorare con il tuo database. Il vero vantaggio di questo (rispetto al metodo di Access), è che dopo aver progettato la tua tabella tramite la GUI, ti mostra l'SQL che verrà eseguito, e quindi puoi imparare da quello.


3
La tua risposta è la soluzione migliore
Omar

14
CREATE TABLE accounts(
    account_id INT NOT NULL AUTO_INCREMENT,
    customer_id INT( 4 ) NOT NULL ,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
    PRIMARY KEY ( account_id )
)

and

CREATE TABLE customers(
    customer_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    address VARCHAR(20) NOT NULL,
    city VARCHAR(20) NOT NULL,
    state VARCHAR(20) NOT NULL,
)

How do I create a 'relationship' between the two tables? I want each account to be 'assigned' one customer_id (to indicate who owns it).

Devi chiederti se questa è una relazione 1 a 1 o una relazione 1 su molti. Cioè, ogni account ha un cliente e ogni cliente ha un account. O ci saranno clienti senza account. La tua domanda implica il secondo.

Se vuoi avere una stretta relazione 1 a 1, unisci le due tabelle.

CREATE TABLE customers(
    customer_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    address VARCHAR(20) NOT NULL,
    city VARCHAR(20) NOT NULL,
    state VARCHAR(20) NOT NULL,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
)

Nell'altro caso, il modo corretto per creare una relazione tra due tabelle è creare una tabella delle relazioni.

CREATE TABLE customersaccounts(
    customer_id INT NOT NULL,
    account_id INT NOT NULL,
    PRIMARY KEY (customer_id, account_id)
    FOREIGN KEY customer_id references customers (customer_id) on delete cascade,
    FOREIGN KEY account_id  references accounts  (account_id) on delete cascade
}

Quindi, se hai un customer_id e desideri le informazioni sull'account, ti iscrivi agli account e agli account dei clienti:

SELECT a.*
    FROM customersaccounts ca
        INNER JOIN accounts a ca.account_id=a.account_id
            AND ca.customer_id=mycustomerid;

A causa dell'indicizzazione, questo sarà incredibilmente veloce.

Puoi anche creare una VISTA che ti dà l'effetto della tabella dei conti clienti combinati mantenendoli separati

CREATE VIEW customeraccounts AS 
    SELECT a.*, c.* FROM customersaccounts ca
        INNER JOIN accounts a ON ca.account_id=a.account_id
        INNER JOIN customers c ON ca.customer_id=c.customer_id;

1
Penso che intendessi ca.no ac.(3 posti).
Vista ellittica

hai scritto PRIMARY KEY (customer_id, account_id)senza virgola dopo di essa
theonlygusti

11

Aggiungendo al commento di ehogue, dovresti far corrispondere la dimensione dei tasti su entrambe le tabelle. Piuttosto che

customer_id INT( 4 ) NOT NULL ,

fallo

customer_id INT( 10 ) NOT NULL ,

e assicurati che anche la colonna int nella tabella dei clienti sia int (10).


7

Alcuni motori MySQL supportano chiavi esterne. Ad esempio, InnoDB può stabilire vincoli basati su chiavi esterne. Se si tenta di eliminare una voce in una tabella che ha dipendenti in un'altra, l'eliminazione avrà esito negativo.

Se stai usando un tipo di tabella in MySQL, come MyISAM, che non supporta chiavi esterne, non colleghi le tabelle da nessuna parte tranne i tuoi diagrammi e query.

Ad esempio, in una query colleghi due tabelle in un'istruzione select con un join:

SELECT a, b from table1 LEFT JOIN table2 USING (common_field);

2

Ecco un paio di risorse che ti aiuteranno a iniziare: http://www.anchor.com.au/hosting/support/CreatingAQuickMySQLRelationalDatabase e http://code.tutsplus.com/articles/sql-for-beginners-part- 3-database-relazioni - net-8561

Inoltre, come altri hanno detto, usa una GUI: prova a scaricare e installare Xampp (o Wamp) che eseguono software server (Apache e mySQL) sul tuo computer. Quindi, quando si accede a // localhost in un browser, selezionare PHPMyAdmin per iniziare a lavorare visivamente con un database mySQL. Come accennato in precedenza, innoDB utilizzato per consentirti di stabilire relazioni come richiesto. Rende più facile vedere cosa stai facendo con le tabelle del database. Ricorda solo di FERMARE i servizi Apache e mySQL al termine: questi possono aprire porte che possono esporti a minacce di hacking / dannose.


Se imposti apache e mysql per servire solo richieste locali, non è necessario interromperli. Oltre ai quali gli utenti dovrebbero avere almeno un firewall software installato se installano questi tipi di servizi. Detto questo, molti router domestici sono dotati di un firewall integrato, quindi le porte non dovrebbero essere aperte comunque a meno che non siano state aperte da qualcuno con accesso al router.
Chris

1

Una delle regole che devi conoscere è che la colonna della tabella a cui vuoi fare riferimento deve essere con lo stesso tipo di dati della tabella di riferimento. 2 se decidi di usare mysql devi usare InnoDB Engine perché secondo la tua domanda è il motore che supporta ciò che vuoi ottenere in mysql.

Di seguito è riportato il codice provalo anche se le prime persone a rispondere a questa domanda hanno fornito al 100% ottime risposte e per favore considerale tutte.

CREATE TABLE accounts(
    account_id INT NOT NULL AUTO_INCREMENT,
    customer_id INT( 4 ) NOT NULL ,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
    PRIMARY KEY (account_id)
)ENGINE=InnoDB;

CREATE TABLE customers(
    customer_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    address VARCHAR(20) NOT NULL,
    city VARCHAR(20) NOT NULL,
    state VARCHAR(20) NOT NULL,
     PRIMARY KEY ( account_id ), 
FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 
)ENGINE=InnoDB; 

0
create table departement(
    dep_id      int primary key auto_increment,
    dep_name    varchar(100) not null,
    dep_descriptin      text,
    dep_photo       varchar(100) not null,
    dep_video       varchar(300) not null
);

create table newsfeeds(
    news_id         int primary key auto_increment,
    news_title      varchar(200) not null,
    news_description    text,
    news_photo          varchar(300) ,
    news_date           varchar(30) not null,
    news_video          varchar(300),
    news_comment        varchar(200),
    news_departement    int foreign key(dep_id) references departement(dep_id)
);

Fornisci alcune spiegazioni sullo schema fornito.
samabcde
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.