2012-07-19 6 views
5

Ich habe meistens MyISAM-Tabellen verwendet, die keine Fremdschlüssel unterstützen. Auf den Stack-Overflow schauend fand ich keine nette, prägnante Erklärung, was ein Fremdschlüssel eigentlich macht. Ich bin meistens interessiert Tabellen verbinden, wo Sie sich ein Schema wie dieses:Wie funktionieren Fremdschlüssel?

customers 
id category_id 

products 
id category_id 

categories 
id 

customerproducts 
customer_id product_id 

Wenn ich Fremdschlüssel auf customerproducts haben, wird es sicher, dass nur gültige Kunden und nur gültig Produkte in dieser Tabelle, aber Was ist, wenn ich versuche, ein Produkt aus der Kategorie Telefone einem Kunden hinzuzufügen, der nur an Kopierern interessiert ist? Werden dadurch die Fremdschlüsseleinschränkungen verletzt?

+0

Mögliche Duplikate: http://stackoverflow.com/questions/4262554/database-design-whats-the-point-of-identifying-foreign-keys, http://stackoverflow.com/ Fragen/18717/sind-Fremdschlüssel-wirklich-notwendig-in-einem-Datenbank-Design, http://stackoverflow.com/questions/83147/whats-wrong-with-foreign-keys – LittleBobbyTables

+0

Alle drei dieser Fragen sind im Wesentlichen fragen warum? Ich versuche zu fragen, wie? Genialer Griff übrigens. –

Antwort

1

Ich bin meistens interessiert Tabellen verbinden, wo Sie sich ein Schema wie dieses:

Sie kein Schema wie das hätte - es ist nicht die Fakten darstellt Sie‘ Interesse an. Lassen Sie uns einige Tabellen in SQL skizzieren. (Getestet in PostgreSQL) Zuerst Kunden und Produkte.

-- 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'); 

Es gibt verschiedene Kategorien für Produkte.

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

Jedes Produkt kann in mehreren Kategorien vorkommen.

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'); 

Ein Kunde könnte an mehreren Produktkategorien interessiert sein.

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'); 

Wenn ich Fremdschlüssel auf customerproducts haben, wird es sicher, dass nur gültige Kunden und nur gültig Produkte in dieser Tabelle erhalten, aber was wäre es, wenn ich versuche, ein Produkt aus der Telefone Kategorie hinzuzufügen ein Kunde vorgesehen als nur Kopierer interessiert?

Kunden sind nicht interessiert an alle Produkt in ihren bevorzugten Kategorien. Beachten Sie die überlappenden Fremdschlüsseleinschränkungen.

Der nächste Einsatz wird fehlschlagen, weil Kunde 1 nicht an Telefonen interessiert ist.

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".