2011-11-09 22 views
6

Podría alguien darme una idea de cómo crear esta estructura de base de datos. Aquí se muestra un ejemplo:Campo SQL con múltiples identificadores de otra tabla

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

ahora tengo otra "productos" de mesa y de ahí me gustaría para almacenar todos los países en los que este producto está disponible:

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. 

Mi pregunta: ¿Cómo ¿Diseño la estructura de la tabla en "productos" para poder almacenar varios países?

Mi mejor idea es poner una cadena separada por comas allí (es decir, "1,2,4"), luego dividir esa cadena para buscar cada entrada. Pero dudo que esta sea la mejor manera de hacer esto?

EDIT: Gracias a todos por su ayuda, increíble! Fue difícil elegir la respuesta correcta, Finalmente elegí Gregs porque me señaló una explicación de JOIN y dio un ejemplo de cómo usarla.

Respuesta

9

Se necesita una tabla de intersección para que many-to-many relación.

Table Country 
CountryID, CountryName 

Table CountryProduct 
CountryID, ProductID 

Table Product 
ProductID, ProductName 

A continuación, Inner Join los 3 mesas para obtener su lista de países & productos.

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

También podría hacer una tercera tabla countries_products con los campos country_id y product_id.

2

Sin desnormalización, que tendrá que añadir una mesa extra

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

De lo que está hablando es de normalización. Tiene una estructura de muchos a muchos, por lo que debe crear otra tabla para vincular los dos. Nunca debería (vale, casi nunca) usar cadenas delimitadas para almacenar una lista de valores en una base de datos relacional.

He aquí un ejemplo de la disposición:

product_countries table 

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

Se puede utilizar una clave externa de la otra tabla, a continuación, hacer a los dos en una clave principal compuesta.

entonces se puede obtener una lista de productos soportados por un identificador de país de esta manera:

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

¿por qué no utilizar una unión? esto siempre me parece un poco extraño – Flo

+0

La lógica al usar un 'JOIN 'sería más confusa para un novato SQL, lo que claramente es el OP. Claro, un 'JOIN' también funcionaría, pero sin él la lógica es más clara y fácil de entender. – Polynomial

+0

¡Gracias a todos y a todos por ayudar! Sí, SQL-newbie aquí. Una pregunta: esa declaración SQL me parece lenta, supongamos que tengo más de 100 productos, ¿no tardaría mucho tiempo en iterar a través de product_countries? – marimba

1

el mejor enfoque para bases de datos relacionales es el siguiente:

Una mesa para coutries, digamos country_id , country_desc (country_id es el principal)

una tabla para productos, digamos product_id, product_desc y tantas columnas como desee (product_id es el principal)

si tuvieras solo un país seguro, bastaría con tener una clave externa apuntando a country_id en cada fila de productos. Tener una clave externa afirma que hay un país real detrás de un country_id que hace referencia a la tabla de países.

En el caso de que tienen varios países para un producto, por lo que añadir una tabla de asociación separada product_id, country_id

ambas claves primaria y tanto extranjeros también.

Cuestiones relacionadas