구분된 목록을 데이터베이스 열에 저장하는 것이 정말 그렇게 나쁜가요?
확인란 집합이 있는 웹 양식을 상상합니다(모두 또는 임의의 확인란을 선택할 수 있습니다.데이터베이스 테이블의 한 열에 저장된 값의 쉼표로 구분된 목록에 저장하기로 선택했습니다.
이제 두 번째 테이블을 만들고 데이터베이스를 적절히 정규화하는 것이 올바른 해결책임을 알고 있습니다.쉬운 솔루션을 구현하는 것이 더 빨랐고, 애플리케이션에 너무 많은 시간을 들이지 않고도 애플리케이션에 대한 개념 증명을 신속하게 수행하고 싶었습니다.
저는 절약된 시간과 간단한 코드가 제 상황에서 가치가 있다고 생각했습니다. 이것이 방어 가능한 디자인 선택인가요, 아니면 처음부터 정규화했어야 했나요?
좀 더 맥락에 따라 공유 폴더에 저장되어 있던 Excel 파일을 근본적으로 대체하는 작은 내부 응용프로그램입니다.프로그램을 정리해서 유지보수를 좀 더 해볼까 해서 물어봅니다.그 안에는 제가 완전히 만족하지 않는 것들이 있는데, 그 중 하나가 이 질문의 주제입니다.
단일 열에 저장된 값의 반복 그룹으로 인해 First Normal Form을 위반하는 것 외에도 쉼표로 구분된 목록에는 더 실용적인 문제가 많이 있습니다.
- 각 값이 올바른 데이터 유형인지 확인할 수 없음: 1,2,3,banana,5를 방지할 방법 없음
- 외부 키 제약 조건을 사용하여 값을 조회 테이블에 연결할 수 없으며 참조 무결성을 적용할 방법이 없습니다.
- 고유성을 적용할 수 없음: 1,2,3,3,3,5를 방지할 방법 없음
- 전체 목록을 가져오지 않으면 목록에서 값을 삭제할 수 없습니다.
- 문자열 열에 맞는 것보다 긴 목록을 저장할 수 없습니다.
- 목록에서 지정된 값을 가진 모든 엔터티를 검색하기 어렵습니다. 비효율적인 테이블 스캔을 사용해야 합니다.MySQL해야 할
idlist REGEXP '[[:<:]]2[[:>:]]'
는 MySQL 8.0에서:idlist REGEXP '\\b2\\b'
- 목록에서 요소를 세거나 다른 집계 쿼리를 수행하기가 어렵습니다.
- 참조하는 룩업 테이블에 값을 조인하기가 어렵습니다.
- 정렬된 순서대로 목록을 가져오기가 어렵습니다.
- 값에 나타나지 않도록 보장된 구분 기호를 선택하기 어렵습니다.
이러한 문제를 해결하려면 수많은 애플리케이션 코드를 작성하여 RDBMS가 이미 제공하는 기능을 훨씬 효율적으로 재창조해야 합니다.
쉼표로 구분된 목록은 제 책의 첫 장을 만들 정도로 충분히 틀렸습니다.SQL 안티패턴, 1권: 데이터베이스 프로그래밍의 함정 피하기
정규화 해제를 사용해야 할 때도 있지만 @OMG Ponies가 언급한 것처럼 예외적인 경우입니다.관계가 없는 "최적화"는 데이터의 다른 용도에 비해 한 가지 유형의 쿼리에 도움이 되므로, 쿼리 중 어떤 것을 특별히 처리해야 하는지 알아야 합니다.
"한 가지 이유는 게으름이었습니다."
경보음이 울립니다.당신이 이런 일을 해야 하는 유일한 이유는 당신이 그것을 "올바른 방법"으로 할 줄 알지만, 당신은 그것을 그렇게 하지 말아야 할 가시적인 이유가 있다는 결론에 도달했기 때문입니다.
다음과 같이 말합니다. 이 방식으로 저장하기로 선택한 데이터가 결코 쿼리할 필요가 없는 데이터라면 선택한 방식으로 저장하는 경우가 있을 수 있습니다.
(일부 사용자는 이전 단락에서 "앞으로 어떤 요구사항이 추가될지 절대 알 수 없다"며 이의를 제기할 것입니다.이 사용자들은 잘못 판단했거나 종교적 확신을 말하고 있습니다.때로는 자신이 가지고 있는 요구사항에 따라 작업하는 것이 유리합니다.)
SO에 대한 질문은 다음과 같습니다.
- 쉼표로 구분된 목록에서 특정 값의 개수를 가져오는 방법
- 쉼표로 구분된 목록에서 2/3/etc 특정 값만 같은 레코드를 가져오는 방법
쉼표로 구분된 목록의 또 다른 문제는 값이 일치하는지 확인하는 것입니다. 텍스트 저장은 오타의 가능성을 의미합니다.
이는 모두 정규화되지 않은 데이터의 증상이며, 정규화된 데이터를 항상 모형화해야 하는 이유를 강조합니다.정규화 해제는 요구사항이 실제로 나타날 때 적용되는 쿼리 최적화가 될 수 있습니다.
일반적으로 어떤 것이든 프로젝트의 요구사항을 충족한다면 방어할 수 있습니다.그렇다고 해서 사람들이 당신의 결정에 동의하거나 방어하고 싶어하는 것은 아닙니다.
일반적으로 이러한 방식으로 데이터를 저장하는 것은 최적이 아니며(예: 효율적인 쿼리를 수행하기가 더 어려운 경우), 양식의 항목을 수정할 경우 유지보수 문제가 발생할 수 있습니다.중간 그라운드를 찾아서 대신 비트 플래그 집합을 나타내는 정수를 사용할 수도 있었겠죠?
네, 정말 그렇게 나쁘다고 생각합니다.그것은 방어할 수 있는 선택이지만, 그렇다고 해서 정확하거나 좋은 것은 아닙니다.
첫번째 정상적인 형태를 깨뜨립니다.
두 번째 비판은 검증이나 바인딩 없이 원시 입력 결과를 데이터베이스에 직접 입력하면 SQL 주입 공격에 노출된다는 것입니다.
여러분이 게으름과 SQL 지식 부족이라고 부르는 것은 초보자들이 만든 것입니다.시간을 내서 제대로 하고 배울 수 있는 기회로 여기는 것을 추천합니다.
아니면 그대로 두고 SQL 주입 공격의 뼈아픈 교훈을 배우십시오.
다중 값 열이 필요했습니다. xml 필드로 구현할 수 있습니다.
필요에 따라 쉼표로 구분하여 변환할 수 있습니다.
Xquery를 사용하여 sql 서버에서 XML 목록을 쿼리합니다.
xml 필드가 되면 몇 가지 우려 사항을 해결할 수 있습니다.
CSV 사용: 각 값이 올바른 데이터 유형인지 확인할 수 없음: 1,2,3,banana,5를 방지할 방법 없음
XML을 사용하면 태그의 값을 올바른 유형으로 강제 지정할 수 있습니다.
CSV 사용: 외부 키 제약 조건을 사용하여 값을 조회 테이블에 연결할 수 없으며 참조 무결성을 적용할 방법이 없습니다.
XML의 경우: 여전히 문제입니다.
CSV 사용: 고유성을 적용할 수 없음: 1,2,3,3,3,5를 방지할 방법 없음
XML의 경우: 여전히 문제입니다.
With CSV: 전체 목록을 가져오지 않으면 목록에서 값을 삭제할 수 없습니다.
XML을 사용하면 단일 항목 제거 가능
CSV 사용: 목록에서 지정된 값을 가진 모든 엔티티를 검색하기가 어렵습니다. 비효율적인 테이블 스캔을 사용해야 합니다.
XML을 사용하면 xml 필드를 인덱싱할 수 있습니다.
CSV 사용: 목록의 요소를 세거나 다른 집계 쿼리를 수행하기 어렵습니다.**
XML을 사용할 경우: 특별히 어렵지 않음
CSV 사용: 참조하는 룩업 테이블에 값을 조인하기 어렵습니다.**
XML을 사용할 경우: 특별히 어렵지 않음
CSV 사용: 정렬된 순서로 목록을 가져오기가 어렵습니다.
XML을 사용할 경우: 특별히 어렵지 않음
CSV 사용: 정수를 문자열로 저장하는 경우 이진 정수를 저장하는 경우보다 공간이 약 두 배 더 많이 소요됩니다.
XML을 사용하면 스토리지가 csv보다 더 열악함
CSV 사용: 많은 쉼표 문자를 추가합니다.
XML의 경우: 쉼표 대신 태그가 사용됩니다.
간단히 말해서, XML을 사용하면 구분 목록의 일부 문제를 해결하고 필요에 따라 구분 목록으로 변환할 수 있습니다.
네, 그 정도입니다.제 견해는 관계형 데이터베이스를 사용하는 것을 좋아하지 않는다면, 더 적합한 대안을 찾으라는 것입니다. 정말 고급 기능을 갖춘 흥미로운 "NOSQL" 프로젝트가 많이 있습니다.
SQL Server의 NTEXT 열에서 키/값 쌍 탭으로 구분된 목록을 4년 이상 사용해 왔는데 작동합니다.쿼리를 생성할 때 유연성을 잃기는 하지만, 반면에 키 값 쌍을 지속/지속하는 라이브러리가 있다면 이는 그리 좋은 생각이 아닙니다.
저는 아마 CSV의 각 필드를 데이터베이스의 별도 열로 만드는 중간 지점을 택할 것입니다. 하지만 (적어도 지금은) 정규화에 대해서는 크게 걱정하지 않습니다.어느 시점에서는 정규화가 흥미로워질 수도 있지만, 모든 데이터를 단일 열에 밀어 넣음으로써 데이터베이스를 사용함으로써 얻을 수 있는 이점은 사실상 없습니다.데이터를 의미 있게 조작하기 위해서는 데이터를 논리적 필드/열/이름을 무엇이라 부르든지 구분해야 합니다.
만약 당신이 고정된 수의 부울 필드를 가지고 있다면, 당신은 다음을 사용할 수 있습니다.INT(1) NOT NULL
(또는BIT NOT NULL
우).CHAR (0)
대해 (null능)해한을 .SET
(정확한 구문은 잊어버립니다.)
언급URL : https://stackoverflow.com/questions/3653462/is-storing-a-delimited-list-in-a-database-column-really-that-bad
'sourcetip' 카테고리의 다른 글
웹 응용프로그램에서 시간대 처리 (0) | 2023.09.25 |
---|---|
Android에서 부팅 시 서비스를 시작하려고 합니다. (0) | 2023.09.25 |
다른 스키마의 사용자에게 권한 부여 (0) | 2023.09.25 |
긴 정수에 대한 최대값 (0) | 2023.09.25 |
하위 폴더를 PHP를 사용하여 WordPress에서 국가 코드로 동적으로 다시 작성 (0) | 2023.09.25 |