2012-07-19 24 views
5

Ho usato principalmente tabelle MyISAM prima, che non supportano chiavi esterne. Guardando allo stack overflow, non ho trovato una spiegazione chiara e concisa di ciò che una chiave straniera sta effettivamente facendo. Sono per lo più interessati a unire le tabelle, in cui si avrebbe uno schema come questo:Come funzionano le chiavi esterne?

customers 
id category_id 

products 
id category_id 

categories 
id 

customerproducts 
customer_id product_id 

Se ho le chiavi esterne su customerproducts, si farà in modo che solo i clienti validi e solo prodotti validi entrare in quel tavolo, ma che dire se provo ad aggiungere un prodotto dalla categoria telefoni a un cliente indicato come uno interessato solo alle fotocopiatrici? Ciò causerà la violazione dei vincoli delle chiavi esterne?

+0

possibili duplicati: http://stackoverflow.com/questions/4262554/database-design-whats-the-point-of-identifying-foreign-keys, http://stackoverflow.com/ domande/18717/are-foreign-keys-veramente-necessari-in-a-database-design, http://stackoverflow.com/questions/83147/whats-wrong-with-foreign-keys – LittleBobbyTables

+0

Tutte e tre queste domande sono essenzialmente chiedendo perché? Sto provando a chiedere come? Incredibile maniglia btw. –

risposta

1

Sono per lo più interessati a unire le tabelle, in cui si avrebbe uno schema come questo:

Non avresti uno schema del genere - non rappresenta i fatti si' interessato. Descriveremo alcune tabelle in SQL. (Testato su PostgreSQL) In primo luogo, clienti e prodotti.

-- Customer names aren't unique. 
create table customers (
    cust_id integer primary key, 
    cust_name varchar(15) not null 
); 
insert into customers values (1, 'Foo'), (2, 'Bar'); 

-- Product names are unique. 
create table products (
    prod_id integer primary key, 
    prod_name varchar(15) not null unique 
); 
insert into products values 
(150, 'Product 1'), (151, 'Product 2'), (152, 'Product 3'); 

Ci sono diverse categorie di prodotti.

create table categories (
    cat_name varchar(15) primary key 
); 
insert into categories values ('Cable'), ('Networking'), ('Phones'); 

Ogni prodotto può apparire in diverse categorie.

create table product_categories (
    prod_id integer not null references products, 
    cat_name varchar(15) not null references categories, 
    primary key (prod_id, cat_name) 
); 

insert into product_categories values 
(150, 'Cable'), (150, 'Networking'), (151, 'Networking'), (152, 'Phones'); 

Un cliente potrebbe essere interessato a diverse categorie di prodotti.

create table customer_category_interests (
    cust_id integer not null references customers, 
    cat_name varchar(15) not null references categories, 
    primary key (cust_id, cat_name) 
); 

-- Nobody's interested in phones 
insert into customer_category_interests values 
(1, 'Cable'), (1, 'Networking'), (2, 'Networking'); 

Se ho le chiavi esterne su customerproducts, si farà in modo che solo i clienti validi e solo prodotti validi entrare in quel tavolo, ma che cosa su se cerco di aggiungere un prodotto dalla categoria telefoni a un cliente contrassegnato come uno interessato solo alle fotocopiatrici?

I clienti non sono interessati a ogni prodotto nelle loro categorie preferite. Nota i vincoli di chiave esterna che si sovrappongono.

create table product_interests (
    cust_id integer not null, 
    prod_id integer not null, 
    cat_name varchar(15) not null, 
    foreign key (cust_id, cat_name) references customer_category_interests, 
    foreign key (prod_id, cat_name) references product_categories, 
    primary key (cust_id, prod_id, cat_name) 
); 

insert into product_interests values 
(1, 150, 'Cable'), (2, 150, 'Networking'); 

Questa prossimo inserto fallirà, perché cliente 1 non è interessato a telefoni.

insert into product_interests values 
(1, 152, 'Phones'); 
 
ERROR: insert or update on table "product_interests" violates foreign key constraint "product_interests_cust_id_fkey" 
DETAIL: Key (cust_id, cat_name)=(1, Phones) is not present in table "customer_category_interests". 
Problemi correlati