SQL Server의 뷰에서 열을 참조하는 외래 키를 가질 수 있습니까?


84

SQL Server 2008에서

TableA(A_ID, A_Data)
TableB(B_ID, B_Data)
ViewC(A_or_B_ID, A_or_B_Data)

그것을 정의 할 수 TableZ(A_or_B_ID, Z_Data)있도록 Z.A_or_B_ID열이 검색된 값으로 제한된다 ViewC? 뷰에 대한 외래 키로이 작업을 수행 할 수 있습니까?

답변:


108

외래 키에서 뷰를 참조 할 수 없습니다.


37
이것은 SQL 서버의 제한입니까 아니면 원하지 않는 것이 있습니까?
Aaron Anodide

1
@Brian 나도 이것이 SQL Server의 제한인지 또는 원하는 불합리한 것인지 아는 데 관심이 있습니다.이 시점에서 FK 지원을 받기 위해 트리거를 사용하여 뷰를 에뮬레이션하려고하기 때문입니다 (MySql을 사용하고 있지만 ).
썰매

4
-이 다음 후속 질문에 좋은 답변입니다 stackoverflow.com/questions/3833150/...
크리스 Halcrow

이 질문에 대한 좋은 대답인지 잘 모르겠습니다. 다른 DBMS에 대한 것이며 뷰가 스키마 세부 정보와 사용자 편의를 숨기도록 설계되었다고 말합니다. 첫째, 좋습니다 ...하지만 이것이 초기 설계를 넘어선 견고한 사용 사례를 찾는 첫 번째 일은 아닙니다. 둘째, FK가 왜 그렇게하지 않는지 잘 모르겠습니다. 뷰는 테이블에서 그릴 필요도없는 쿼리 일 수 있으며, 함께 결합 된 상수 묶음 일 수 있습니다.이 경우 외래 키는 상당히 합리적으로 보입니다. 더 깊은 것을 바라지 않을 이유가 있다면.
George Mauer

27

이전 SQL Server 버전에서는 외래 키가 트리거를 통해서만 가능했습니다. 삽입 된 값이 관련 테이블 중 하나에도 표시되는지 확인하는 삽입 트리거를 만들어 사용자 지정 외래 키를 모방 할 수 있습니다.


3
StackOverflow에 오신 것을 환영합니다. 해결 방법을 제공하기 때문에 귀하의 답변에서 가치를 찾았지만 정답은 허용되는 답변이며 질문은 4 년 이상되었으므로 투표하지 않고이 의견 없이는 남기고 싶지 않았습니다.
jachguate

16

A_or_B_IDTableZ에서 정말 필요한 경우 두 가지 유사한 옵션이 있습니다.

1) 테이블 z에 nullable A_IDB_ID열을 A_or_B_ID추가하고,이 두 열에 ISNULL을 사용하여 계산 된 열을 만들고 , 둘 중 하나만 A_ID또는 B_IDnull이 아닌 CHECK 제약 조건을 추가합니다.

2) 현재 A 또는 B 중 어느 하나를 포함하는 제약 생성 테이블 (Z)에 TABLENAME 열을 추가 A_ID하고 B_ID그들의 적절한 테이블 () CASE 식을 사용하여 이름이 유일한 비 - 널이다 계산 열로. 그들도 계속 유지하십시오

두 경우 모두 기본 테이블에 대한 적절한 외래 키를 가질 수있는 A_IDB_ID열이 있습니다. 차이점은 계산되는 열에 있습니다. 또한 2 개의 ID 열의 도메인이 겹치지 않는 경우 위의 옵션 2에서 TableName이 필요하지 않습니다. 단, 케이스 표현식이 어떤 도메인 A_or_B_ID 에 속 하는지 결정할 수있는 한

(내 서식 수정에 대한 의견에 감사드립니다)


A_or_B_ID
백틱에

저는 레거시 시스템에 몇 가지 기능을 추가하는 작업을 진행 중이며 이는 기존 시스템과 새로운 기능을 함께 패치 할 수있는 좋은 방법입니다. 감사합니다!
David Gunderson


4

다른 옵션이 있습니다. TableA 및 TableB를 TablePrime이라는 새 테이블의 하위 클래스로 취급합니다. TableB의 ID 값이 TableA의 ID 값과 일치하지 않도록 조정합니다. TablePrime의 ID를 PK로 만들고 TableA 및 TableB의 모든 (조정 된) ID를 TablePrime에 삽입합니다. TableA와 TableB가 PK에서 TablePrime의 동일한 ID에 대한 FK 관계를 갖도록합니다.

이제 상위 유형 / 하위 유형 패턴이 있으며 TablePrime (-A- 또는 -B 중 하나 를 원하는 경우 ) 또는 개별 테이블 중 하나 ( A 또는 B 만 원하는 경우)에 제약 조건을 만들 수 있습니다. .

더 자세한 정보가 필요하시면 문의하십시오. A와 B가 상호 배타적인지 또는 작업중인 것이 동시에 둘 다일 수 있도록하는 변형이 있습니다. 가능하면 FK에서 공식화하는 것이 가장 좋습니다.


2

값이 존재하면 true를 반환하고 그렇지 않으면 false를 반환하는 fCheckIfValueExists (columnValue)라는 사용자 정의 함수를 참조하는 제약 조건을 추가하는 것이 더 쉽습니다.

장점은 여러 열을 수신하고, 계산을 수행하고, null을 허용하고, 기본 키에 정확하게 일치하지 않는 값을 허용하거나, 조인 결과와 비교할 수 있다는 것입니다.

단점은 옵티마이 저가 모든 외래 키 트릭을 사용할 수 없다는 것입니다.


1
단점은 옵티마이 저가 그의 모든 외래 키 트릭을 사용할 수 없다는 것입니다. ... ... 그리고 삽입 / 업데이트하는 모든 행에 대해 함수가 실행된다는 것입니다 (세트에 너무 좋지 않음).
jimbobmcgee

1

죄송합니다. 엄밀히 말하면 뷰에 외래 키를 설정할 수 없습니다. 그 이유는 다음과 같습니다.

InnoDB는 외래 키를 특징으로하는 MySQL 용 내장 스토리지 엔진입니다. 모든 InnoDB 테이블은 engine = 'InnoDB'로 information_schema.tables에 등록됩니다.

information_schema.tables에 등록 된 뷰에는 NULL 스토리지 엔진이 있습니다. MySQL에는 정의되지 않은 스토리지 엔진이있는 테이블에 외래 키를 포함하는 메커니즘이 없습니다.

감사!


이 질문은 SQL 서버에 관한 것입니다
George Mauer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.