【发布时间】:2015-08-01 13:10:48
【问题描述】:
项目总结
我们正在创建一个“数字”厨房,您可以在其中添加冰箱、冰柜等中的物品。然后可以在网络应用程序上查看这些物品,这样您就可以随时随地了解厨房里的杂货.
数据库
总共有三张桌子。
列表
这包含 ListID 和这些列表的名称,例如“冰箱”或“冰箱”。所以,这基本上就是“容器”。
项目
然后是 Items,其中包含 itemtypes,即 Milk,1 加仑。
列表项
然后是 ListItems(对不起,名称有点混乱),其中包含 特定 项。 Items 只是一个可以添加的项目表,ListItems 是添加 项。因此,添加到该表中的行自然具有 Lists 表上的 List 的外键和 Item 表上的 Item 的外键项目表。该表的主键是一个超级键,几乎由它的所有属性组成。
两个ListItem可以引用同一个Item和同一个List,只要它们有不同的属性即可。它们可能在不同的日期到期或具有不同的单位尺寸。唯一使 Item 独一无二的是名称,就像添加“Ham”一样,它永远不会覆盖“Milk”。添加另一个“牛奶”将被视为相同的 Item
问题
这是一个例子。您想添加两个单独的项目。第一个是 3 条火腿,每条 200 克,将于 5 月 28 日到期。 下一个是另一个火腿,这是一个单一的,但 500 克,将于 5 月 31 日到期:
ListID 1 指的是名为 Fridge 的 List。 ItemID 1 指的是名为 Ham 的项目。
看到问题了吗?外键相同。
它在我们的本地数据库中存储得很好,但是在与 Azure 数据库同步时,我们收到以下错误:
{"Violation of PRIMARY KEY constraint 'PK__#A4D1762__44A4C03D49E5E4B8'.
Cannot insert duplicate key in object 'dbo.@changeTable'.
The duplicate key value is (1, 1).\r\n
The data for table-valued parameter \"@changeTable\" doesn't conform to the table type of the parameter.
SQL Server error is: 3602, state: 30\r\nThe statement has been terminated."}
这是糟糕的数据库设计还是 Azure 的问题?
更新 1
DDL 在本地数据库中的外观如下:
CREATE TABLE [dbo].[ListItems] (
[ListId] INT NOT NULL,
[ItemId] INT NOT NULL,
[Amount] INT NOT NULL,
[Volume] INT NOT NULL,
[Unit] NVARCHAR(MAX) NULL,
[ShelfLife] DATETIME NOT NULL,
CONSTRAINT [pk_ListItems] PRIMARY KEY CLUSTERED ([ShelfLife], [Volume], [Amount], [ItemId], [ListId]),
CONSTRAINT [fk_ListItems] FOREIGN KEY ([ListId]) REFERENCES [dbo].[Lists] ([ListId]) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT [fk_ListItems2] FOREIGN KEY ([ItemId]) REFERENCES [dbo].[Items] ([ItemId]) ON DELETE CASCADE ON UPDATE CASCADE
);
还有 Azure 数据库 DDL:
CREATE TABLE [dbo].[ListItems] (
[ListId] INT NOT NULL,
[ItemId] INT NOT NULL,
[Amount] INT NOT NULL,
[Volume] INT NOT NULL,
[Unit] NVARCHAR (MAX) NULL,
[ShelfLife] DATETIME NOT NULL,
CONSTRAINT [PK_dbo.ListItems] PRIMARY KEY CLUSTERED ([ListId] ASC, [ItemId] ASC, [Amount] ASC, [Volume] ASC, [ShelfLife] ASC),
CONSTRAINT [FK_dbo.ListItems_dbo.Items_ItemId] FOREIGN KEY ([ItemId]) REFERENCES [dbo].[Items] ([ItemId]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.ListItems_dbo.Lists_ListId] FOREIGN KEY ([ListId]) REFERENCES [dbo].[Lists] ([ListId]) ON DELETE CASCADE
);
PK CONSTRAINT 行略有不同,但属性相同。会不会是这个问题?
【问题讨论】:
-
在我看来,您的主键在 Azure 系统上设置不正确。如错误消息所述,重复键值为 (1,1),但您的主键还需要包含金额、体积、单位等。
-
你提到它
stores just fine on your local database,但是你不会有与 Azure db 相同的主键约束,否则它也会失败。你能分享一些本地和 Azure db 的 DDL 代码吗? -
也许您应该考虑在 ListItems 表中添加一些标识列并将其作为主键?那么,您当前的“超级键”可能只是一个唯一索引(以避免重复)。
-
两者同步时是否会出现问题?传统的做法是在这里使用guid,这样key可以在任一数据库中生成,并保证在整个系统中是唯一的。
-
我已经为两个 ListItem 表添加了 DDL 代码!
标签: c# sql sql-server database microsoft-sync-framework