Database design 数据库中的两个键表?

Database design 数据库中的两个键表?,database-design,Database Design,我试图设计一个数据库表,列出距离“城市a”到“城市B”的“价格”。城市B到城市A的价格应该相同,因此将此信息存储两次是多余的 我应该如何设计表格,以便给定两个城市,我可以查找价格而不必存储两次(如A,B,price和B,A,price) 我的想法是,我可以“按字母顺序”存储它,这样“较早的”城市将始终位于左列,而较晚的城市将显示在右列。然后,当查询数据库时,我只需要做同样的事情,并在必要时交换顺序。好的,您可以使用select中的OR子句(其中(A='city A'和B='city B')或(

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

我应该如何设计表格,以便给定两个城市,我可以查找价格而不必存储两次(如
A,B,price
B,A,price



我的想法是,我可以“按字母顺序”存储它,这样“较早的”城市将始终位于左列,而较晚的城市将显示在右列。然后,当查询数据库时,我只需要做同样的事情,并在必要时交换顺序。

好的,您可以使用select中的OR子句(其中(A='city A'和B='city B')或(A='city B'和B='city A')),但诚实地存储它两次可能意味着更快的查询。

您所说的是复合键的概念,其中值1和值2都决定要提取哪个记录


我想说的是,简单地将其设计为您的字段city_1、city_2、price。然后以编程方式处理逻辑以定义正确的查询。

最好的快速通用解决方案可能是使用约束,例如CityId1在表中只存储一次城市对。将数据以alpha顺序与第一个alpha city I一起存储n在插入前使用存储过程对数据进行排序的第一列。在两个城市列上创建一个唯一索引。创建一个检索存储过程,首先对提供的城市进行排序,然后查询表。下面是使用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'

这太模糊了…我该如何“以编程方式处理逻辑”?这正是我要问的。它不仅仅是一个复合键,它是一个顺序无关紧要的复合键。如果你问的是如何“以编程方式处理逻辑”,那么也许这不应该仅仅被标记为“数据库设计”自然……当设计数据库时,你必须考虑查询数据库……也许我没有用我可以/应该有的所有标签来标记它,但是问题本身还是应该说:)使用“或”解决方案也不会阻止它被添加到数据库中两次(更糟的是,价格不同)!这可能会导致一些重大的不一致。事实上,后一种解决方案也是同样的问题。B市对A市的价格不一定相同。有很多理由不这样做,无论是从需求方面还是从供应方面。@Walter:你怎么能不知道我的申请就这么说?你知道“价格”是什么吗?类似于我的问题修正案。这似乎是一个合理的解决方案。数据库(如PostgreSQL)是否允许此类约束,或者我是否只在代码中强制执行此类约束?可以添加这样的约束,但我不认为有理由在这里使DB模式复杂化。看到这里很酷,我不知道你可以在SQL:-D中完成所有这些