내 데이터에 대한 크로스 참조 테이블/쿼리를 어떻게 만들려고합니까?

StackOverflow https://stackoverflow.com/questions/321127

문제

데이터베이스에 두 개의 간단한 테이블이 있습니다. 카드의 ID, 이름 및 텍스트가 포함 된 "카드"테이블, 카드의 ID가 포함 된 "gulings"테이블 및 카드의 판결을 자세히 설명하는 텍스트.

판결 텍스트에서는 종종 데이터베이스에 다른 카드에 대한 참조가 있습니다. 각 카드는 텍스트의 따옴표 내에 캡슐화되기 때문에 텍스트에서 이것을 찾기가 쉽습니다. 판결의 텍스트 내에서 여러 카드를 참조하는 것은 드문 일이 아닙니다.

내가하고 싶은 것은 카드에 대한 쿼리를 제출할 때 카드를 통해 카드를 직접 참조하는 모든 판결 기록을 찾을 수 있도록 크로스 참조 테이블 (또는 충분히 효율적인 절차)을 만들 수 있습니다. 신분증 및 카드 이름이 텍스트에 참조되는 모든 판결 기록을 가져옵니다.

이것에 접근하는 가장 좋은 방법은 무엇입니까? 저의 환경은 SQL 2005이지만 모든 종류의 "DB Agnostic"솔루션은 여기에서 크게 허용됩니다.

도움이 되었습니까?

해결책

이것은 교차 참조 테이블에 의해 해결되는 상당히 단순하고 일반적인 관계형 문제처럼 보입니다. 예를 들어:

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

이것은 모두 내 머리 꼭대기에서 벗어 났고 테스트되지 않았으므로 구문 오류가있을 수 있습니다.

당신의 프론트 엔드는 참조를 유지할 책임이 있습니다. 판결 텍스트 등에 카드 이름 주위에 인용문을 넣는 것을 잊어 버리는 사람의 문제를 피하기 때문에 이것은 아마도 바람직 할 것입니다.

다른 팁

참조를 저장하는 다른 테이블을 만드는 것이 좋습니다. 그런 다음이 테이블을 유지하는 삽입 및 업데이트 트리거를 작성하십시오. 이렇게하면 원하는 데이터를 반환 할 수있는 더 빠른 쿼리가있을 것입니다.

처음 에이 테이블을 채우는 것이 조금 어려울 수 있다는 것을 알고 있습니다. 그래서 아래에 샘플 데이터 (및 쿼리)가 표시되어 시작하는 데 사용할 수 있습니다.

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

편집하다:

내가 다른 테이블을 제안한 이유는이 쿼리, 특히 큰 테이블의 성능에 실망했기 때문입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top