2012-01-15 26 views
10

Creé una tabla que contiene información sobre una empresa. Un atributo es su número de teléfono. Una empresa puede tener muchos números de teléfono.SQL: atributos de varios valores

¿Cómo creo atributos multivalor en SQL?

+2

Usted ** no ** - que viola incluso la primera forma normal de diseño de la base de datos. Si su empresa tiene varios números de teléfono, los coloca en una tabla separada y los vincula a la tabla de la empresa. –

Respuesta

7

En general, no existe el atributo multivaluado en las bases de datos relacionales.

Posibles soluciones para su problema:

  1. Crear una tabla separada para almacenar los números de teléfono que hace referencia a su mesa empresa mediante clave principal y contiene el número de filas por undefinite empresa.

    Por ejemplo, si usted tiene la tabla company con campos id, name, address, ... continuación, puede crear una tabla con los campos companyphonescompanyid, phone.

  2. (NO se recomienda en general, pero si solo necesita mostrar una lista de teléfonos en el sitio web podría ser una opción) Almacenar teléfonos en un solo campo usando varchar (...) o texto y agregar separadores entre números .

+0

+1 Tenga en cuenta que en la opción 1, 'companyphones' debe tener su propia clave única; esta podría ser la combinación de' companyid' y 'phone', o podría ser un campo de identificación separado. –

15

En una tabla separada como:

CREATE TABLE Company 
(
    Id int identity primary key, 
    Name nvarchar(100) not null UNIQUE --UNIQUE is optional 
) 
GO 
CREATE TABLE CompanyPhones 
(
    Id int identity primary key, 
    Phone nvarchar(100) not null, 
    CompanyId int NOT NULL REFERENCES Company(Id) ON DELETE CASCADE 
) 

Cómo utilizar estas estructuras:

SELECT CompanyPhones.Phone 
FROM Company 
JOIN CompanyPhones 
    ON Company.Id = CompanyPhones.CompanyId 
WHERE Company.Name=N'Horns and Hoogs Ltd.' 
+0

Hay un error en su consulta en la primera línea. Debería ser 'SELECT CompanyPhones.Phone'. Es una edición de un carácter y, por lo tanto, no puedo cambiarla. SO necesita un mínimo de 6 cambios de caracteres para una edición exitosa. – pratnala

+0

@pratnala Gracias, corregido –

6

Además de respuestas Oleg y de Sergey, una tercera opción podría ser la creación de teléfono múltiple campos en la tabla de la empresa, por ejemplo, como SwitchboardPhone y FaxNumber para la centralita principal y la línea de fax, respectivamente.

Este tipo de solución generalmente se considera como una forma de desnormalización, y generalmente solo es adecuada cuando hay un pequeño número de opciones múltiples, cada una con un rol claramente definido. Por lo tanto, por ejemplo, esta es una forma bastante común de representar números fijos y móviles/celulares para una tabla de lista de contactos, pero sería completamente inadecuado para una lista de todas las extensiones de teléfono dentro de una compañía.

+0

¿Pero y si hay 2 números de fax? Boom – pratnala

+0

@pratnala: Boom de hecho; pero, ¿cuántas empresas sabe que tienen más de un fax (o incluso tienen uno en estos días)? –

+0

Bastante justo. Pero siento que es bueno no dejar nada al azar. – pratnala

3

Existen algunas posibilidades en diferentes implementaciones de RDBMS.

Por ejemplo, en PostgreSQL puede utilizar array o hstore o incluso JSON (in 9.3 version):

create table Company1 (name text, phones text[]); 

insert into Company1 
select 'Financial Company', array['111-222-3333', '555-444-7777'] union all 
select 'School', array['444-999-2222', '555-222-1111']; 

select name, unnest(phones) from Company1; 

create table Company2 (name text, phones hstore); 

insert into Company2 
select 'Financial Company', 'mobile=>555-444-7777, fax=>111-222-3333'::hstore union all 
select 'School', 'mobile=>444-999-2222, fax=>555-222-1111'::hstore; 

select name, skeys(phones), svals(phones) from Company2  

sql fiddle demo

También puede crear índices en estos campos - https://dba.stackexchange.com/questions/45820/how-to-properly-index-hstore-tags-column-to-faster-search-for-keys, Can PostgreSQL index array columns?

En SQL Server, puede utilizar el tipo de datos XML para almacenar múltiples valores:

create table Company (name nvarchar(128), phones xml); 

insert into Company 
select 'Financial Company', '<phone type="mobile">555-444-7777</phone><phone>111-222-3333</phone>' union all 
select 'School', '<phone>444-999-2222</phone><phone type="fax">555-222-1111</phone>' 

select 
    c.name, 
    p.p.value('@type', 'nvarchar(max)') as type, 
    p.p.value('.', 'nvarchar(max)') as phone 
from Company as c 
    outer apply c.phones.nodes('phone') as p(p) 

sql fiddle demo

También puede create xml indexes en la columna de tipo XML.

Cuestiones relacionadas