예, 끔찍한 생각입니다.
가는 대신 :
SELECT Deal.Name, DealCategory.Name
FROM Deal
INNER JOIN
DealCategories ON Deal.DealID = DealCategories.DealID
INNER JOIN
DealCategory ON DealCategories.DealCategoryID = DealCategory.DealCategoryID
WHERE Deal.DealID = 1234
이제 가야합니다 :
SELECT Deal.ID, Deal.Name, DealCategories
FROM Deal
WHERE Deal.DealID = 1234
그런 다음 응용 프로그램 코드에서 해당 쉼표 목록을 개별 숫자로 나누고 데이터베이스를 별도로 쿼리해야합니다.
SELECT DealCategory.Name
FROM DealCategory
WHERE DealCategory.DealCategoryID IN (<<that list from before>>)
이 디자인 반 패턴은 관계형 모델링에 대한 완전한 오해 (테이블을 무서워 할 필요는 없습니다. 테이블은 친구입니다. 테이블을 사용하십시오) 또는 쉼표로 구분 된 목록을 가져 와서 나누는 것이 더 빠르다는 기묘하게 잘못된 생각에서 비롯됩니다. 응용 프로그램 코드에서 링크 테이블을 추가하는 것보다 결코 아닙니다 . 세 번째 옵션은 외래 키를 설정할 수있을 정도로 SQL에 대해 확신이없고 유능하지 않다는 것입니다.
SQL Antipatterns (Karwin, 2010)는이 반 패턴 ( 'Jaywalking'이라고 함), 15-23 페이지에 전체 장을 할당합니다. 또한 저자는 비슷한 질문을 SO 에 게시했습니다 . 그가 지적한 요점은이 예제에 적용됩니다.
- 특정 카테고리의 모든 거래를 쿼리하는 것은 다소 복잡합니다 (문제를 해결하는 가장 쉬운 방법은 정규식이지만 정규식 자체는 문제임).
- 외래 키 관계가 없으면 참조 무결성을 강화할 수 없습니다. DealCategory nr을 삭제 한 경우 그런 다음 애플리케이션 코드에서 # 26 카테고리에 대한 참조를 찾아 각 거래를 거쳐 삭제해야합니다. 이것은 데이터 계층에서 처리해야하는 것이며 응용 프로그램에서 처리해야하는 것은 매우 나쁜 일 입니다.
- 집계 쿼리 (
COUNT
, SUM
등), 다시, '거의 불가능'에 '복잡'에서 다릅니다. 개발자에게 해당 카테고리의 거래 수와 함께 모든 카테고리 목록을 얻는 방법을 문의하십시오. 적절한 디자인으로, 그것은 네 줄의 SQL입니다.
- 업데이트가 훨씬 어려워집니다 (즉, 5 개 범주의 거래가 있지만 두 개를 제거하고 다른 세 개를 추가하려고 함). 그것은 적절한 디자인을 가진 세 줄의 SQL입니다.
- 결국
VARCHAR
리스트 길이 제한에 직면하게됩니다. 4,000자가 넘는 쉼표로 구분 된 목록이 있으면 어쨌든 몬스터가 느리게 진행될 가능성이 높습니다.
- 데이터베이스에서 목록을 가져 와서 분리 한 다음 다른 쿼리에 대해 데이터베이스로 돌아가는 것은 본질적으로 하나의 쿼리보다 느립니다.
TLDR : 근본적으로 결함이있는 디자인이며, 확장 성이 떨어지며, 가장 간단한 쿼리조차도 복잡성을 증가 시키며 즉시 사용이 가능하여 애플리케이션 속도가 느려집니다.