如何为我的数据创建交叉引用表/查询?
Posted
技术标签:
【中文标题】如何为我的数据创建交叉引用表/查询?【英文标题】:How do I create a cross reference table/query for my data? 【发布时间】:2008-11-26 15:37:38 【问题描述】:我的数据库中有两个简单的表。包含卡片 ID、名称和文本的“卡片”表,以及包含卡片 ID 和详细说明卡片规则的文本的“规则”表。
在裁决文本中经常会提到数据库中的另一张牌。在文本中很容易找到这一点,因为每张卡片都包含在文本的引号中。在裁决文本中引用多张卡片的情况并不少见。
我想做的是能够创建一个交叉引用表(或程序,如果它足够高效的话),这样当我提交卡片查询时,我可以找到所有直接引用该卡片的裁决记录通过Id获取卡片,获取文本中引用卡片名称的所有裁决记录。
解决这个问题的最佳方法是什么?我的环境是 SQL 2005,但任何类型的“与 DB 无关”的解决方案在这里都被广泛接受。
【问题讨论】:
【参考方案1】:这似乎是一个相当简单且常见的关系问题,可以通过交叉引用表来解决。例如:
CREATE TABLE dbo.Cards (
id INT NOT NULL,
name VARCHAR(50) NOT NULL,
card_text VARCHAR(4000) NOT NULL,
CONSTRAINT PK_Cards PRIMARY KEY CLUSTERED (id)
)
GO
CREATE TABLE dbo.Card_Rulings (
card_id INT NOT NULL,
ruling_number INT NOT NULL,
ruling_text VARCHAR(4000) NOT NULL,
CONSTRAINT PK_Card_Rulings PRIMARY KEY CLUSTERED (card_id, ruling_number)
)
GO
CREATE TABLE dbo.Card_Ruling_Referenced_Cards (
parent_card_id INT NOT NULL,
ruling_number INT NOT NULL,
child_card_id INT NOT NULL,
CONSTRAINT PK_Card_Ruling_Referenced_Cards PRIMARY KEY CLUSTERED (parent_card_id, ruling_number, child_card_id)
)
GO
ALTER TABLE dbo.Card_Rulings
ADD CONSTRAINT FK_CardRulings_Cards FOREIGN KEY (card_id) REFERENCES dbo.Cards(id)
GO
ALTER TABLE dbo.Card_Ruling_Referenced_Cards
ADD CONSTRAINT FK_CardRulingReferencedCards_CardRulings FOREIGN KEY (parent_card_id, ruling_number) REFERENCES dbo.Card_Rulings (card_id, ruling_number)
GO
ALTER TABLE dbo.Card_Ruling_Referenced_Cards
ADD CONSTRAINT FK_CardRulingReferencedCards_Cards FOREIGN KEY (child_card_id) REFERENCES dbo.Cards(id)
GO
要获得一张卡片的所有卡片规则:
SELECT *
FROM dbo.Cards C
INNER JOIN dbo.Card_Rulings CR ON CR.card_id = C.id
WHERE C.id = @card_id
要获取给定卡片在裁决中引用的所有卡片:
SELECT C.*
FROM dbo.Card_Rulings CR
INNER JOIN dbo.Card_Ruling_Referenced_Cards CRRC ON CRRC.parent_card_id = CR.card_id
INNER JOIN dbo.Cards C ON C.id = CRRC.child_card_id
WHERE CR.card_id = @card_id
这完全是我的想法,没有经过测试,所以可能存在语法错误等。
您的前端将负责维护引用。这可能是可取的,因为它避免了有人忘记在规则文本中为卡名加上引号等问题。
【讨论】:
【参考方案2】:我建议您创建另一个表来存储您的引用。然后,创建一个维护该表的插入和更新触发器。这样,您可以更快地查询来返回您正在查找的数据。
我知道最初填充此表可能有点困难,这就是为什么我在下面显示一些示例数据(和查询),您可以使用它们来帮助您入门。
Declare @Card Table(Id Int, Name VarChar(20), CardText VarChar(8000))
Declare @Ruling Table(CardId Int, CardRuling VarChar(8000))
Insert Into @Card Values(1, 'Card 1', 'This is the card ID = 1')
Insert Into @Card Values(2, 'Card 2', 'This is the card id = 2.')
Insert Into @Card Values(3, 'Card 3', 'This is the card id = 3.')
Insert Into @Ruling Values(1, 'This is the ruling for 1 which references "2"')
Insert Into @Ruling Values(2, 'This is the ruling for 2 which references nothing')
Insert Into @Ruling Values(3, 'This is the ruling for 3 which references "1" and "2"')
Declare @CardId Int
Set @CardId = 1
Select *
From @Card As Card
Inner Join @Ruling As Ruling
On Card.Id = Ruling.CardId
Left Join @Card As CardReferences
On Ruling.CardRuling Like '%"' + Convert(VarChar(10), CardReferences.Id) + '"%'
编辑:
我建议另一个表的原因是因为您可能会对这个查询的性能感到失望,尤其是对于大型表。
【讨论】:
以上是关于如何为我的数据创建交叉引用表/查询?的主要内容,如果未能解决你的问题,请参考以下文章