首页 文章

如何为我的数据创建交叉引用表/查询?

提问于
浏览
2

我的数据库中有两个简单的表 . 包含卡片的ID,名称和文本的“卡片”表,以及包含卡片ID的“裁定”表格,以及详细说明卡片裁定的文本 .

通常在执政文本中,有一个对数据库中另一张卡的引用 . 在文本中很容易找到它,因为每张卡都封装在文本中的引号内 . 在裁决文本中引用多张牌并不罕见 .

我想做的是能够创建一个交叉引用表(或程序,如果它足够有效),以便当我提交卡的查询,我可以找到直接引用该卡的所有统治记录通过Id并获取文本中引用卡名称的所有裁定记录 .

什么是最好的方法来解决这个问题?我的环境是SQL 2005,但是这里大大接受任何类型的“数据库不可知”解决方案 .

2 回答

  • 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
    

    这一切都是我的头脑,并没有经过测试,因此可能存在语法错误等 .

    您的前端将负责维护引用 . 这可能是可取的,因为它避免了某人忘记在裁决文本中放置卡片名称等的问题等 .

  • 4

    我建议您创建另一个存储引用的表 . 然后,创建一个用于维护此表的插入和更新触发器 . 这样,您将有一个更快的查询来返回您要查找的数据 .

    我认识到最初填充此表可能有点困难,这就是为什么我在下面显示一些示例数据(和查询),您可以使用它来帮助您入门 .

    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) + '"%'
    

    编辑:

    我建议另一个表的原因是因为您可能会对此查询的性能感到失望,尤其是对于大型表 .

相关问题