SQL:多值属性

use*_*176 13 sql database

我创建了一个包含公司信息的表.一个属性是他们的电话号码.公司可以有很多电话号码.

如何在SQL中创建多值属性?

Ole*_*Dok 16

在一个单独的表中,如:

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
)
Run Code Online (Sandbox Code Playgroud)

如何使用这些结构:

SELECT CompanyPhones.Phone
FROM Company
JOIN CompanyPhones
  ON Company.Id = CompanyPhones.CompanyId
WHERE Company.Name=N'Horns and Hoogs Ltd.'
Run Code Online (Sandbox Code Playgroud)


Ser*_*sev 8

关系数据库中通常没有多值属性.

您的问题的可能解决方案:

  1. 创建一个单独的表,用于存储按主键引用公司表的电话号码,并且每个公司包含不确定的行数.

    例如,如果您有company包含字段的表,id, name, address, ...则可以创建companyphones包含字段的表companyid, phone.

  2. (一般不推荐,但如果你只需要显示在网站上的手机的列表,这可能是一个选项)使用VARCHAR(...)或文本和添加数字之间的分隔符在一个字段中存储的电话.


小智 6

除了奥列格和谢尔盖的回答,第三个选择可能是创建公司表中的多个手机领域-例如,作为SwitchboardPhoneFaxNumber分别用于主交换机和传真线路.

这种类型的解决方案通常被视为非规范化的一种形式,并且通常仅适用于存在少量多个选项的情况,每个选项具有明确定义的角色.

因此,例如,这是表示联系人列表表的固定电话和移动电话/电话号码的一种常见方式,但完全不适合公司内所有电话分机的列表.


Rom*_*kar 5

RDBMS 的不同实现有一些可能性。

例如,在PostgreSQL 中,您可以使用数组hstore甚至JSON(在 9.3 版本中)

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    
Run Code Online (Sandbox Code Playgroud)

sql fiddle demo

您还可以在这些字段上创建索引 - https://dba.stackexchange.com/questions/45820/how-to-properly-index-hstore-tags-column-to-faster-search-for-keys可以 PostgreSQL 索引数组列?

SQL Server 中,您可以使用 xml 数据类型来存储多值:

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)
Run Code Online (Sandbox Code Playgroud)

sql fiddle demo

您还可以在 xml 类型列上创建 xml 索引