2011-11-09 24 views
6

Czy ktoś mógłby mi dać pomysł, jak utworzyć tę strukturę bazy danych. Oto przykład:Pole SQL z wieloma identyfikatorami innej tabeli

Table "countries": 
id, countryname 
1, "US" 
2, "DE" 
3, "FR" 
4, "IT" 

Teraz mam kolejny „produkty” stół i tam chciałbym przechowywać wszystkie kraje, w których produkt będzie dostępny:

Table "products": 
id,productname,countries 
1,"product1",(1,2,4) // available in countries US, DE, IT. 
2,"product2",(2,3,4) // available in countries DE, FR, IT. 

Moje pytanie: Jak zrobić Projektuję strukturę tabeli w "produktach", aby móc przechowywać wiele krajów?

Najlepszym pomysłem jest umieszczenie w nim ciągu oddzielanego przecinkami ("1,2,4"), a następnie podzielenie tego ciągu w celu wyszukania każdego wpisu. Ale wątpię, czy to najlepszy sposób na zrobienie tego?

EDYCJA: Dziękuję wszystkim za pomoc, niesamowite! Trudno było wybrać właściwą odpowiedź, W końcu wybrałem Gregsa, ponieważ wskazał mi wyjaśnienie JOIN i podał przykład, jak z niego korzystać.

Odpowiedz

9

potrzebny jest stół przecięcia tej many-to-many relacji.

Table Country 
CountryID, CountryName 

Table CountryProduct 
CountryID, ProductID 

Table Product 
ProductID, ProductName 

Następnie Inner Join wszystkie 3 stoły, aby uzyskać listę krajów & produktów.

Select * From Country 
Inner Join CountryProduct On Country.CountryID = CountryProduct.CountryID 
Inner Join Product On CountryProduct.ProductID = Product.ProductID 
1

Można również utworzyć trzeci stół countries_products z polami country_id i product_id.

2

Bez denormalizing, trzeba dodać dodatkowy stół

Table Product countries 
ProductID CountryID 
1   1 
1   2 
1   4... 
2

To, o czym mówisz, to normalizacja. Masz strukturę wiele do wielu, więc powinieneś utworzyć kolejną tabelę, aby połączyć te dwa. Nigdy nie powinieneś (dobrze, prawie nigdy) używać rozgraniczonych łańcuchów do przechowywania listy wartości w relacyjnej bazie danych.

Oto przykład konfiguracji:

product_countries table 

productid | countryid 
----------+----------- 
1   | 1 
1   | 2 
1   | 4 
2   | 2 
2   | 3 
2   | 4 

Można użyć klucza obcego do każdej innej tabeli, a następnie dokonać ich obu do złożonego klucza podstawowego.

Następnie można uzyskać listę obsługiwanych produktów dla identyfikatora kraju takim jak ten:

SELECT * FROM products, product_countries 
WHERE products.id = product_countries.productid 
AND product_countries.countryid = $cid 
+0

dlaczego nie używać złączenia? to zawsze wydaje mi się nieco dziwne. – Flo

+0

Logika przy użyciu 'JOIN' byłaby bardziej myląca dla początkującego SQL'a, co wyraźnie oznacza OP. Jasne, "JOIN" też by działało, ale bez niego logika jest jaśniejsza i łatwiejsza do zrozumienia. – Polynomial

+0

Dziękuję i wszystkim innym za pomoc !! Tak, nowicjusz SQL tutaj. Jedno zapytanie: że instrukcja SQL wydaje mi się powolna - przypuśćmy, że mam 100000+ produktów, czy nie zajmie to dużo czasu iteracji w product_countries? – marimba

1

najlepszym podejściem do relacyjnych baz danych jest następujący:

Jedna tabela dla coutries, powiedzmy country_id , country_desc (country_id to primary)

jedna tabela produktów, powiedzmy, product_id, product_desc i tyle kolumn, ile chcesz (product_id ma podstawowe znaczenie)

Jeśli na pewno miałeś tylko jeden kraj, wystarczy, że w każdym rzędzie produktu będzie znajdować się klucz obcy wskazujący numer_dom. Posiadanie klucza zagranicznego zapewnia, że ​​istnieje rzeczywisty kraj behing country_id odnoszący się do tabeli krajów.

W twoim przypadku masz kilka krajów w odniesieniu do produktu, więc dodać osobny stół stowarzyszenie product_id, country_id

oba klawisze podstawowa i zarówno zagranicznych, jak również.

Powiązane problemy