数据库中的双键表?

时间:2010-12-29 22:30:52

标签: database-design

我正在尝试设计一个数据库表,列出距离“城市A”到“城市B”的“价格”。城市B到城市A应该是相同的价格,因此将这些信息存储两次是多余的。

如何设计表格,以便给定2个城市,我可以查看价格,而无需将其存储两次(A,B,priceB,A,price)?


我的想法是,我可以“按字母顺序”存储它,以便“较早”的城市始终位于左栏,而后面的城市则会出现在右栏中。然后在查询数据库时,我必须做同样的事情并在必要时交换订单。

4 个答案:

答案 0 :(得分:2)

你可以在你的选择中使用OR子句(WH =(A ='城市A'和B ='城市B')或(A ='城市B'和B ='城市A'),但是诚实地存储它两次将意味着更快的查询。

答案 1 :(得分:2)

可能最好的快速和通用解决方案是使用约束,例如所有行中的CityId1< CityId2,并在从表中检索数据时使用某种OR或双重选择。

如果它更多的是关于“数据库设计”,那么只需将其输入您最喜欢的ER建模工具,并观察结果。

答案 2 :(得分:1)

仅在表格中存储城市对一次。使用存储过程将数据按照alpha顺序存储在第一列中的第一个alpha城市,以便在插入之前对数据进行排序。在两个城市列上创建唯一索引。创建一个检索存储过程,首先对提供的城市进行排序,然后查询表。以下是使用SQL Server 2K8 Express的一些快速工作。

CREATE TABLE [dbo].[Distance](
    [D_Id] [int] IDENTITY(1,1) NOT NULL,
    [D_City1] [nchar](10) NOT NULL,
    [D_City2] [nchar](10) NOT NULL,
    [D_Distance] [int] NOT NULL
) ON [PRIMARY]

GO


Insert Distance
Values
('a','b',30)
,('b','c',40)
,('c','z',40)
,('d','z',40)
,('e','z',40)

select * from Distance where D_City1 = 'a' and D_City2 = 'b'
Drop procedure Get_Distance ;
GO
Create procedure Get_Distance 
@1City nvarchar(10)
, @2City nvarchar(10)

AS
Declare @1AlphaCity nvarchar(10), @2AlphaCity nvarchar(10)
Select @1City, @2City, @1AlphaCity, @2AlphaCity
set @1AlphaCity = @1City
Set @2AlphaCity = @2City
If @1AlphaCity > @2AlphaCity 
BEGIN
    Set @1AlphaCity = @2City
    Set @2AlphaCity = @1City
END
Select @1City, @2City, @1AlphaCity, @2AlphaCity

GO

EXEC dbo.Get_Distance 'C', 'B'

答案 3 :(得分:0)

您说的是复合键的概念,其中value_1和value_2都决定了哪个记录被拉出。

我想说的只是将你的字段设为city_1,city_2,price。然后以编程方式处理逻辑以定义正确的查询。