我创建了一个包含公司信息的表。一个属性是他们的电话号码。公司可以有很多电话号码。
如何在SQL中创建多值属性?
答案 0 :(得分: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
)
如何使用这些结构:
SELECT CompanyPhones.Phone
FROM Company
JOIN CompanyPhones
ON Company.Id = CompanyPhones.CompanyId
WHERE Company.Name=N'Horns and Hoogs Ltd.'
答案 1 :(得分:8)
关系数据库中通常没有多值属性。
您的问题的可能解决方案:
创建一个单独的表,用于存储按主键引用公司表的电话号码,并且每个公司包含不确定的行数。
例如,如果您的表格company
包含字段id, name, address, ...
,那么您可以创建一个包含字段companyphones
的表companyid, phone
。
(一般情况下不推荐,但如果您只需要在网站上显示手机列表,这可能是一个选项)使用varchar(...)或文本在单个字段中存储电话并在两者之间添加分隔符号。
答案 2 :(得分:6)
除Oleg和Sergey的答案外,第三个选项可能是在公司表上创建多个电话字段 - 例如,对于主交换机和传真线,SwitchboardPhone
和FaxNumber
,分别
这种类型的解决方案通常被视为非规范化的一种形式,并且通常仅适用于存在少量多个选项的情况,每个选项都有明确定义的角色。
因此,例如,这是表示联系人列表中的固定电话和移动电话号码的常用方法,但完全不适合公司内所有电话分机的列表。
答案 3 :(得分:4)
在RDBMS的不同实现中存在一些可能性。
例如,在 PostgreSQL 中,您可以使用array或hstore甚至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 强>
您还可以在这些字段上创建索引 - https://dba.stackexchange.com/questions/45820/how-to-properly-index-hstore-tags-column-to-faster-search-for-keys,Can PostgreSQL index array columns?
在 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)
<强> sql fiddle demo 强>
您还可以在xml类型列上create xml indexes。