사용자 정의 필드 용 데이터베이스를 설계하는 방법은 무엇입니까?


145

내 요구 사항은 다음과 같습니다

  • 모든 데이터 유형의 사용자 정의 필드를 동적으로 추가 할 수 있어야합니다.
  • UDF를 빠르게 쿼리 할 수 ​​있어야합니다.
  • 데이터 유형을 기반으로 UDF에서 계산을 수행 할 수 있어야합니다.
  • 데이터 유형에 따라 UDF를 정렬 할 수 있어야합니다.

기타 정보:

  • 나는 주로 성능을 찾고 있습니다
  • UDF 데이터를 첨부 할 수있는 수백만 개의 마스터 레코드가 있습니다.
  • 마지막으로 확인했을 때 현재 데이터베이스에 50mil 이상의 UDF 레코드가있었습니다.
  • 대부분의 경우 UDF는 수천 개의 마스터 레코드에만 첨부됩니다.
  • UDF는 결합되거나 키로 사용되지 않습니다. 쿼리 나 보고서에 사용 된 데이터 일뿐입니다.

옵션 :

  1. StringValue1, StringValue2 ... IntValue1, IntValue2, ... 등으로 큰 테이블을 만듭니다. 나는이 아이디어가 싫지만 다른 아이디어보다 더 나은 이유를 말해 줄 수 있다면 고려할 것입니다.

  2. 필요에 따라 새 열을 추가하는 동적 테이블을 작성하십시오. 모든 열을 색인화하지 않으면 성능이 느려질 것이라고 생각하기 때문에이 아이디어가 마음에 들지 않습니다.

  3. UDFName, UDFDataType 및 Value를 포함하는 단일 테이블을 작성하십시오. 새 UDF가 추가되면 해당 데이터 만 가져와 지정된 유형으로 구문 분석하는 View를 생성하십시오. 구문 분석 기준을 충족하지 않는 항목은 NULL을 반환합니다.

  4. 데이터 유형 당 하나씩 여러 UDF 테이블을 작성하십시오. 따라서 UDFStrings, UDFDates 등에 대한 테이블이 있습니다. 아마도 # 2와 동일하게 수행하고 새 필드가 추가 될 때마다 View를 자동 생성 할 것입니다.

  5. XML 데이터 유형? 나는 이것들과 함께 일한 적이 없지만 그들이 언급 한 것을 보았습니다. 그들이 특히 내가 원하는 결과를 줄 것인지 확실하지 않습니다.

  6. 다른 것?


7
: 마틴 파울러 2 (사용자 갱신 스키마) 또는 5 (인덱스 XML의 LOB) 권장 martinfowler.com/bliki/UserDefinedField.html
닐 맥기

동적 데이터베이스 스키마 에 대한 StackOverflow 질문도 참조하십시오 .
FloverOwe

답변:


49

성능이 주요 관심사 인 경우 UDF 당 테이블 # 6을 사용합니다 (실제로 # 2의 변형). 이 답변은 이러한 상황과 설명 된 데이터 배포 및 액세스 패턴에 대한 설명에 맞게 조정되었습니다.

장점 :

  1. 일부 UDF에는 전체 데이터 세트의 작은 부분에 대한 값이 있음을 나타내므로 별도의 테이블은 UDF를 지원하는 데 필요한만큼만 테이블이 크기 때문에 최상의 성능을 제공합니다. 관련 지수에 대해서도 마찬가지입니다.

  2. 또한 집계 또는 다른 변환을 위해 처리해야하는 데이터의 양을 제한하여 속도를 향상시킵니다. 데이터를 여러 테이블로 분할하면 UDF 데이터에 대한 일부 집계 및 기타 통계 분석을 수행 한 다음 외래 키를 통해 결과를 마스터 테이블에 조인하여 집계되지 않은 속성을 얻을 수 있습니다.

  3. 데이터가 실제로 무엇인지 반영하는 테이블 / 열 이름을 사용할 수 있습니다.

  4. 데이터 유형을 정의하고 제한 조건, 기본값 등을 사용하여 데이터 도메인을 정의 할 수있는 완전한 제어 권한이 있습니다. 즉석 데이터 형식 변환으로 인한 성능 저하를 과소 평가하지 마십시오. 이러한 제약 조건은 RDBMS 쿼리 최적화 프로그램이보다 효과적인 계획을 개발하는 데 도움이됩니다.

  5. 외래 키를 사용해야하는 경우 내장 된 선언적 참조 무결성이 트리거 기반 또는 응용 프로그램 수준 제약 조건 적용으로 거의 수행되지 않습니다.

단점 :

  1. 이것은 많은 테이블을 만들 수 있습니다. 스키마 분리 및 / 또는 명명 규칙을 적용하면이를 완화 할 수 있습니다.

  2. UDF 정의 및 관리를 운영하는 데 더 많은 애플리케이션 코드가 필요합니다. 나는 이것이 원래 옵션 1, 3 및 4에 필요한 코드보다 여전히 적은 코드를 기대합니다.

다른 고려 사항 :

  1. UDF를 그룹화하는 데 적합한 데이터의 특성에 관한 것이 있으면 권장해야합니다. 이렇게하면 해당 데이터 요소를 단일 테이블로 결합 할 수 있습니다. 예를 들어 색상, 크기 및 비용에 대한 UDF가 있다고 가정합니다. 데이터 경향은이 데이터의 대부분의 인스턴스가

     'red', 'large', 45.03 

    오히려

     NULL, 'medium', NULL

    이러한 경우, 1 개의 테이블에 3 개의 열을 결합하여 눈에 띄는 속도 패널티가 발생하지 않으며 값이 NULL이 아니기 때문에 2 개의 테이블을 만들지 않아도됩니다. 이는 3 개의 열에 모두 액세스해야 할 때 필요한 2 개의 조인입니다. .

  2. 많이 채워지고 자주 사용되는 UDF에서 성능 벽에 도달하면 마스터 테이블에 포함되도록 고려해야합니다.

  3. 논리 테이블 디자인을 사용하면 특정 시점으로 이동할 수 있지만 레코드 수가 엄청 나면 RDBMS에서 어떤 테이블 파티셔닝 옵션을 제공하는지 살펴 봐야합니다.


1
점검표! 나와 필 사이의 농담으로, 규칙에 위배되지 않기를 바랍니다.
GunnerL3510

고마워, 나는 이것의 변형을 할 것이라고 생각한다. UDF 데이터의 대부분은 참조 목적으로 만 사용해야하는 매핑되지 않은 가져 오기 필드에서 가져온 것이므로 하나의 테이블에 넣기를 원합니다. 다른 UDF는 필요에 따라 정의되며 (사전 식별 할 수 없습니다. 일반적으로 일부 프로세스를 변경하거나 몇 달 동안 특별한 것을 추적하기로 결정할 때 생성됩니다) 일반적으로 쿼리에 사용됩니다. 이 값의 각 논리 단위에 대해 별도의 테이블을 만들 것이라고 생각합니다.
Rachel

날짜 / 버전 UDF가있는 테이블로 작업하고 있으며이 값을 stackoverflow.com/a/123481/328968로 사용 하여 최신 값을 얻습니다.
Peter

22

나는 한 기록 이 문제에 대해 많은 . 가장 일반적인 해결책은 Entity-Attribute-Value 반 패턴이며 옵션 # 3에서 설명하는 것과 유사합니다. 이 디자인을 전염병처럼 피하십시오 .

진정으로 역동적 인 사용자 정의 필드가 필요할 때이 솔루션에 사용하는 것은 XML을 BLOB에 저장하여 언제든지 새 필드를 추가 할 수 있다는 것입니다. 그러나 속도를 높이려면 검색하거나 정렬해야하는 각 필드에 대해 추가 테이블을 작성하십시오 (필드 당 테이블이 아니라 검색 가능한 필드 당 테이블 ). 이를 때때로 거꾸로 된 인덱스 디자인이라고합니다.

이 솔루션에 대한 2009 년 흥미로운 기사를 여기에서 읽을 수 있습니다 : http://backchannel.org/blog/friendfeed-schemaless-mysql

또는 문서 중심의 데이터베이스를 사용하여 문서 당 사용자 정의 필드가있을 것으로 예상됩니다. Solr을 선택합니다 .


1
옵션 3을 피해야하는 이유를 설명 할 수 있습니까? 나는 당신의 몇 가지 예를 살펴 보았지만 실제로는 내가하려는 것과 동일하지 않습니다. 모든 속성을 저장할 장소가 아니라 추가 데이터를 저장할 장소를 원합니다.
Rachel

2
우선, 누가 NULL 속성을 만들지 않겠습니까? 모든 속성을 고유하게 만들지 않고 속성을 어떻게 고유하게 만들겠습니까? 거기서부터 계속됩니다. 논리적 엔티티 레코드를 삽입하고 다시 가져 오기 위해 일종의 맵핑 클래스를 작성해야하는 시점까지 RDBMS가 이미 제공하는 기능을 제공하기 위해 애플리케이션 코드를 작성하게됩니다.
Bill Karwin

2
짧은 대답은 "데이터와 메타 데이터를 혼합하지 마십시오"입니다. 메타 데이터 식별자를 데이터 문자열로 저장 fieldname하거나 tablename저장하는 varchar 열을 만들면 많은 문제가 시작됩니다. 또한 다음을 참조하십시오 : en.wikipedia.org/wiki/Inner-platform_effect
Bill Karwin

2
@Thomas : 반전 된 인덱스 디자인에서 데이터 유형 및 UNIQUE 및 FOREIGN KEY와 같은 제약 조건에 표준 스키마 솔루션을 사용할 수 있습니다. EAV를 사용할 때는 전혀 작동하지 않습니다. 나는 EAV와 거꾸로 된 인덱스 공유가 단순히 행 당 다른 속성을 지원하기 때문에 비 관계형이라는 특성에 동의하지만 그것은 타협점입니다.
Bill Karwin

2
@thitami, 지난 몇 년 동안 배운 것은 모든 솔루션이 앱에 적합한 솔루션이라는 것입니다. EAV조차 일부 특정 앱에는 가장 나쁜 솔루션 일 수 있습니다. 검색어를 모르면 최적화 전략을 선택할 수 없습니다. 모든 종류의 최적화는 다른 쿼리를 희생하면서 특정 쿼리를 향상시킵니다.
Bill Karwin

10

아마도 다음 구조의 테이블을 만들 것입니다.

  • varchar 이름
  • varchar 유형
  • 십진수
  • varchar StringValue
  • 날짜 날짜 값

정확한 유형의 과정은 요구 사항에 따라 다릅니다 (물론 사용중인 dbms에 따라 다름). int와 boolean에 NumberValue (10 진수) 필드를 사용할 수도 있습니다. 다른 유형도 필요할 수 있습니다.

값을 소유 한 마스터 레코드에 대한 링크가 필요합니다. 각 마스터 테이블에 대해 사용자 필드 테이블을 작성하고 간단한 외래 키를 추가하는 것이 가장 쉽고 빠릅니다. 이를 통해 사용자 필드별로 쉽고 빠르게 마스터 레코드를 필터링 할 수 있습니다.

어떤 종류의 메타 데이터 정보를 원할 수도 있습니다. 따라서 다음과 같이 끝납니다.

테이블 UdfMetaData

  • int id
  • varchar 이름
  • varchar 유형

테이블 마스터

  • int Master_FK
  • int MetaData_FK
  • 십진수
  • varchar StringValue
  • 날짜 날짜 값

무엇을하든 테이블 구조를 동적으로 변경 하지는 않습니다 . 유지 보수의 악몽입니다. 나는 또한 XML 구조를 사용 하지 않을 것이다 . 그것들은 너무 느리다.


나는 당신의 전략을 좋아하고 어쩌면 그것을 선택할 수 있지만 2017 년에는 다른 것을 선택할 것입니까? json처럼
maztt

프로젝트에서 우리는 json과 비슷한 것으로 직렬화되는 자체 데이터 구조를 구현했습니다. 캐스팅 및 프로그래밍 언어 통합없이 데이터를 읽고 쓰는 유형 저장 인터페이스가 특징입니다. 정말 좋습니다. 데이터베이스의 모든 종류의 "문서"와 동일한 문제가 있습니다. 특정 값을 쿼리하기 어렵고 "문서"외부의 데이터를 쉽게 참조 할 수 없습니다. 사용법에 따라 두 가지 모두 문제가되지 않습니다.
Stefan Steinegger

그 외에도 2011 년에 제안한 것은 여전히 ​​유효한 솔루션입니다.
Stefan Steinegger

10

이것은 MongoDB 또는 CouchDB와 같은 비 관계형 솔루션으로 더 잘 해결 될 수있는 문제처럼 들립니다.

둘 다 동적 스키마 확장을 허용하면서 원하는 튜플 무결성을 유지할 수 있습니다.

Bill Karwin에 동의합니다. EAV 모델은 성능이 좋지 않습니다. 관계형 시스템에서 이름-값 쌍을 사용하는 것은 본질적으로 나쁘지는 않지만 이름-값 쌍이 완전한 정보 튜플을 만드는 경우에만 잘 작동합니다. 그것을 사용하면 런타임에 테이블을 동적으로 재구성해야하며 모든 종류의 일이 힘들어지기 시작합니다. 쿼리는 피벗 유지 관리의 연습이되거나 튜플 재구성을 객체 계층으로 밀어야합니다.

개체 계층에 스키마 규칙을 포함시키지 않으면 null 값 또는 누락 된 값이 유효한 항목인지 또는 항목이 없는지 확인할 수 없습니다.

스키마를 효율적으로 관리 할 수 ​​없습니다. 100 자 varchar가 "value"필드에 올바른 유형입니까? 200 자? 대신 nvarchar 여야합니까? 어려운 트레이드 오프가 될 수 있으며 세트의 동적 특성에 인공 한계를 설정 해야하는 결과로 끝납니다. "사용자 정의 필드는 x 개만 가질 수 있으며 각 길이는 y 자만 가능합니다.

MongoDB 또는 CouchDB와 같은 문서 지향 솔루션을 사용하면 단일 튜플 내에서 사용자와 관련된 모든 속성을 유지합니다. 조인은 문제가 아니기 때문에 과대 광고에도 불구하고 조인과 잘 어울리지 않기 때문에 인생은 행복합니다. 사용자는 약 4MB에 도달 할 때까지 관리하기 어려운 길이만큼 원하는 수만큼 속성을 정의 할 수 있습니다.

ACID 수준의 무결성이 필요한 데이터가있는 경우 관계형 데이터베이스에있는 고 무결성 데이터와 비 관계형 저장소에있는 동적 데이터를 사용하여 솔루션 분할을 고려할 수 있습니다.


6

사용자 정의 열을 추가하는 사용자를 제공하더라도 해당 열에 대한 쿼리가 제대로 수행되는 것은 아닙니다. 쿼리 디자인에는 성능이 우수한 여러 측면이 있으며, 그 중 가장 중요한 것은 먼저 저장해야하는 항목에 대한 적절한 사양입니다. 따라서 기본적으로 사용자가 사양에 대한 생각없이 스키마를 작성하고 해당 스키마에서 정보를 신속하게 도출 할 수 있도록 하려는가? 그렇다면 사용자가 데이터에 대한 수치 분석을 수행하려는 경우 특히 그러한 솔루션이 잘 확장되는 것은 분명하지 않습니다.

옵션 1

IMO는이 접근 방식을 통해 스키마가 의미하는 바에 대한 지식없이 보고서 디자이너에게 재앙이되고 악몽이 될 수 있습니다. 즉, 어떤 열에 어떤 데이터가 저장되는지 알기 위해서는 메타 데이터가 있어야합니다. 해당 메타 데이터가 엉망이되면 데이터를 호스 핑 할 가능성이 있습니다. 또한 잘못된 열에 잘못된 데이터를 쉽게 넣을 수 있습니다. ( "무엇입니까? String1에는 수녀원의 이름이 들어 있습니다. Chalie Sheen이 가장 좋아하는 약이라고 생각했습니다.")

옵션 3,4,5

IMO, 요구 사항 2, 3 및 4는 EAV의 모든 변형을 제거합니다. 이 데이터를 쿼리, 정렬 또는 계산해야하는 경우 EAV는 크툴 후의 꿈이며 개발 팀과 DBA의 악몽입니다. EAV는 성능 측면에서 병목 현상을 발생 시키며 원하는 정보를 신속하게 얻는 데 필요한 데이터 무결성을 제공하지 않습니다. 쿼리는 신속하게 크로스 탭 고 디안 매듭으로 바뀝니다.

옵션 2,6

그것은 실제로 하나의 선택을 남깁니다 : 사양을 수집하고 스키마를 구축하십시오.

고객이 저장하고자하는 데이터에 대해 최상의 성능을 원한다면 가능한 효율적으로 저장되도록 요구 사항을 이해하기 위해 개발자와 작업하는 과정을 거쳐야합니다. 테이블의 스키마를 기반으로 양식을 동적으로 작성하는 코드를 사용하여 나머지 테이블과 별도의 테이블에 계속 저장할 수 있습니다. 열에 확장 된 속성을 허용하는 데이터베이스가있는 경우이를 사용하여 양식 빌더가 멋진 레이블, 툴팁 등을 사용하여 스키마를 추가하기 만하면됩니다. 어느 쪽이든 보고서를 효율적으로 작성하고 실행하려면 데이터를 올바르게 저장해야합니다. 해당 데이터에 널이 많으면 일부 데이터베이스는 해당 유형의 정보를 저장할 수 있습니다. 예를 들어

분석, 필터링 또는 정렬을 수행하지 않아도되는 데이터 만있는 경우 EAV의 변형으로 트릭을 수행 할 수 있습니다. 그러나 요구 사항을 감안할 때 가장 효율적인 솔루션은 이러한 새 열을 별도의 테이블에 저장하고 해당 테이블에서 동적으로 양식을 작성하더라도 적절한 사양을 얻는 것입니다.

스파 스 열


5
  1. 데이터 유형 당 하나씩 여러 UDF 테이블을 작성하십시오. 따라서 UDFStrings, UDFDates 등에 대한 테이블이 있습니다. 아마도 # 2와 동일하게 수행하고 새 필드가 추가 될 때마다 View를 자동 생성 할 것입니다.

내 연구에 따르면 데이터 유형에 따라 여러 테이블이 성능에 도움이되지 않습니다. 특히 50 개 이상의 UDF를 가진 20K 또는 25K 레코드와 같은 대량 데이터가있는 경우. 성능이 최악이었습니다.

다음과 같은 여러 열이있는 단일 테이블을 사용해야합니다.

varchar Name
varchar Type
decimal NumberValue
varchar StringValue
date DateValue

이것은 정확하고 공표되어야합니다. Phil의 2011 년 이전 답변은 더 이상 오늘 좋은 조언이 아닙니다.
Yap Kai Lun Leon

SQL에서 그러한 프로세스를 수행하는 방법에 대한 간단한 예를 얻을 수 있습니까?
Niroj

답장이 늦어서 죄송하지만 같은 데이터베이스 구조를 원합니다. @Niroj를받지 못했습니다. 원하는대로 자세하게 설명해 주시겠습니까?
계약자 Amit

4

이것은 문제가되는 상황이며 "올바른"해결책은 없습니다. 그러나 옵션 1은 단순성과 성능 측면에서 모두 최고 일 것입니다.

또한 일부 상용 엔터프라이즈 응용 프로그램에 사용되는 솔루션입니다.

편집하다

현재 사용 가능하지만 질문이 원래 요청되었을 때 존재하지 않았거나 적어도 성숙하지 않은 다른 옵션은 DB에서 json 필드를 사용하는 것입니다.

많은 관계형 DB는 이제 json 기반 필드 (동적 하위 필드 목록을 포함 할 수 있음)를 지원하고 이에 대한 쿼리를 허용합니다.

사후

MySQL


1
수백 개의 사용되지 않는 열을 생성한다는 아이디어가 싫습니다. SQL 데이터베이스 디자인에 대해 배우고 읽은 것에 반대합니다. 현재 1300 개가 넘는 서로 다른 사용자 정의 값이 있지만 그 중 다수는 단순히 다른 이름을 가진 기존 항목의 복제물입니다.
Rachel

단일 테이블에 대해 1300 개의 다른 UDF? 각 사용자는 UDF를 추가하거나 일부 고급 사용자 만 추가 할 수 있습니까?
Ophir Yoktan

가져 오기 프로세스의 일부입니다 ... 매핑되지 않은 데이터를 사용자 정의 필드에 추가합니다. 매핑되지 않은 데이터를 기존 UDF 필드에 매핑하는 데 시간이 걸리지 않기 때문에 새로운 필드를 만들며 수년에 걸쳐 많은 것이 추가되었습니다.
Rachel

2

나는 경험이 있거나 1, 3 및 4를 가지고 있으며 모두 데이터가 무엇인지 명확하지 않거나 데이터를 동적 유형의 레코드로 분류하는 일종의 소프트 분류로 명확하지 않습니다.

XML을 사용 해보고 싶을 것입니다 .XML 내용에 대해 스키마를 적용하여 데이터 유형 등을 확인하면 UDF 데이터의 차이 집합을 보유하는 데 도움이됩니다. 최신 버전의 SQL Server에서는 XML 필드를 인덱싱하여 성능을 향상시킬 수 있습니다. 예를 들어 ( http://blogs.technet.com/b/josebda/archive/2009/03/23/sql-server-2008-xml-indexing.aspx 참조 )


솔직히 XML을 전혀 보지 않았습니다. 그것의 주요 단점은 그것이 어떻게 작동하고 그것에 대해 쿼리하는 법을 배워야한다는 것입니다. 그리고 다른 옵션보다 성능이 떨어질 수 있다고 들었습니다
Rachel

1
나는 이것을 위해 xml을 사용하지 않을 것이다 : 그것은 일을 할 수 있고, 과거에는 xml에서 이와 같은 것을 구현했지만 데이터 구조가 커지고 코드 복잡성이 높아 성능이 상당히 나 빠졌다.
Kell

2

SQL Server를 사용하는 경우 sqlvariant 유형을 간과하지 마십시오. 꽤 빠르며 일을해야합니다. 다른 데이터베이스에는 비슷한 것이있을 수 있습니다.

XML 데이터 유형은 성능상의 이유로 좋지 않습니다. 서버에서 계산을 수행하는 경우 지속적으로 직렬화를 해제해야합니다.

옵션 1은 나쁘고 울퉁불퉁 해 보이지만 성능 측면에서 가장 좋습니다. 필자는 성능을 이길 수 없기 때문에 Field00-Field99라는 열로 테이블을 만들었습니다. INSERT 성능도 고려해야 할 수도 있는데,이 경우에도 마찬가지입니다. 깔끔하게 보이려면 언제든지이 테이블에 뷰를 작성할 수 있습니다!


감사합니다. SQL 변형에 대해 다시 살펴 보겠습니다. 나의 가장 큰 관심사는 성능이며, 어떻게 처리 할 것인지 잘 모르겠습니다. 특히 5 천만 행 이상에 대해 이야기하는 경우
Rachel

sql_varients는 LIKE 절과 함께 사용할 수 없다는 것을 알았습니다 ... 그것은 나에게 큰 단점입니다. 나는 각 UDF에 대한 뷰를 생성 할 경우 물론, 그때 SQL_VARIANT_PROPERTY에 따라 적절한 데이터 형식으로 캐스팅 할 수 (값이 'baseType 여기서')는 ... 여전히 성능은 나쁜 것 같아
레이첼

LIKE를 사용할 수 있지만 먼저 값을 캐스트해야합니다. LIKE는 varchar에서만 작동하므로 sql_variant를 varchar로 캐스팅해야합니다. UDF가 varchar인지 여부를 알고있는 한 (예 : 유형이 다른 곳에 저장되어 있기 때문에) 모든 행을 varchar로 필터링 한 다음 LIKE 쿼리를 캐스팅하고 실행할 수 있습니다. select * FROM MyTable 여기서 variant_type = 'v'Cast (variant_value as varchar (max)) LIKE 'Blah %'이런 식으로 정수를 문자열로 변환하지 않으므로 속도가 느려집니다.
팀 로저스

특히 수백만 행에서 성능이 어떻게 수행되는지 확인하려면 몇 가지 테스트를 실행해야합니다. sql_varients를 사용한 성능에 대한 온라인 기사를 알고 있습니까? 특히 캐스팅과 매우 많은 레코드가 있습니까?
Rachel

1

SharePoint는 옵션 1을 사용하며 합리적인 성능을 제공합니다.


1

나는이 옵션들 (옵션 6? :)을 사용하지 않고 과거에 이것을 성공적으로 관리했습니다.

사용자가 (xml로 저장하고 사용자 지정 모델링 도구를 통해 노출) 모델 생성 테이블 및 뷰에서 기본 테이블을 사용자 정의 데이터 테이블과 조인하기위한 모델을 만듭니다. 따라서 각 유형에는 핵심 데이터가있는 기본 테이블과 사용자 정의 필드가있는 사용자 테이블이 있습니다.

문서를 예로 들어 보면 전형적인 필드는 이름, 유형, 날짜, 저자 등입니다. 이것은 핵심 테이블에 있습니다. 그런 다음 사용자는 contract_end_date, renewal_clause, blah blah blah와 같은 고유 필드를 사용하여 고유 한 특수 문서 유형을 정의합니다. 해당 사용자 정의 문서에는 공통 기본 키에서 결합 된 핵심 문서 테이블 인 xcontract 테이블이 있습니다 (따라서 xcontracts 기본 키는 코어 테이블의 기본 키에서도 외래 임). 그런 다음이 두 테이블을 래핑하는 뷰를 생성합니다. 쿼리 속도가 빠릅니다. 추가 비즈니스 규칙을 뷰에 포함시킬 수도 있습니다. 이것은 저에게 정말 효과적이었습니다.


1

Google 데이터베이스는 사용자가 7k 개가 넘는 "사용자 정의 필드"를 보유한 SaaS 앱 (헬프 데스크 소프트웨어)을 지원합니다. 우리는 결합 된 접근법을 사용합니다 :

  1. (EntityID, FieldID, Value)데이터 검색을 위한 테이블
  2. 데이터 entities표시 하는 데 사용되는 모든 엔티티 값을 보유 하는 테이블 의 JSON 필드 (이 방법으로 값을 얻기 위해 백만 개의 JOIN이 필요하지 않습니다).

이 답변에서 제안하는 것처럼 "데이터 유형 당 테이블"을 갖도록 # 1을 더 분할 할 수 있습니다. 이렇게하면 UDF를 색인화 할 수도 있습니다.

추신 : "Entity-Attribute-Value"접근 방식을 방어하기위한 몇 단어 우리는 수십 년 동안 # 2없이 # 1을 사용했으며 정상적으로 작동했습니다. 때로는 사업 결정입니다. 앱을 다시 작성하고 DB를 다시 디자인 할 시간이 있습니까? 아니면 요즘에는 정말 저렴한 클라우드 서버에 몇 가지 비용을 지불 할 수 있습니까? 그건 그렇고, 우리가 # 1 접근법을 사용했을 때, DB는 수백만 명의 사용자가 액세스 한 수백만 개의 엔티티를 보유하고 있었고 16GB 듀얼 코어 DB 서버는 잘 작동했습니다.


@Alex 안녕하세요. 비슷한 문제가 발생했습니다. 잘 이해하면 1) custom_fields1 => last_concert_year, 2 => band, 3 => music과 같은 값을 저장 하는 custom_fields_values테이블과 001, 1, 1976 002, 1, 1977 003, 2, Iron Maiden003, 3 값 을 가진 테이블 , Metal 예제가 당신에게 의미가 있고 형식에 대해 죄송합니다 바랍니다!
thitami

@thitami은 정확하지 않습니다. 귀하의 예를 다음 : 나는이 bands행을 가진 테이블을 1,'Iron Maiden'다음 custom_fields행과 1,'concert_year' | 2,'music'다음 custom_fields_values행이1,1,'1977'|1,2,'metal'
알렉스

0

의견에서 UDF 필드가 사용자가 올바르게 매핑하지 않은 가져온 데이터를 덤프해야한다는 것을 알았습니다.

다른 옵션은 각 사용자가 작성한 UDF 수를 추적하고 6 (또는 다른 임의의 다른 임의의 한계) 사용자 정의 필드 상단을 사용할 수 있다고 말함으로써 필드를 재사용하도록 강제하는 것입니다.

이와 같은 데이터베이스 구조화 문제가 발생하면 응용 프로그램의 기본 디자인 (귀하의 경우 가져 오기 시스템)으로 돌아가서 몇 가지 제한을 두는 것이 가장 좋습니다.

이제 내가 할 일은 사용자에 대한 링크가 추가 된 옵션 4 (EDIT)입니다.

general_data_table
id
...


udfs_linked_table
id
general_data_id
udf_id


udfs_table
id
name
type
owner_id --> Use this to filter for the current user and limit their UDFs
string_link_id --> link table for string fields
int_link_id
type_link_id

이제 성능을 최적화하고 색인을 올바르게 작성하기위한보기를 작성하십시오. 이 수준의 정규화는 DB 풋 프린트를 더 작게 만들지 만 애플리케이션은 더 복잡합니다.


0

이 유형의 시스템은 인증을받은 전자 상거래 CMS 플랫폼 인 Magento 에서 사용 되었으므로 # 4를 추천 합니다. fieldIdlabel 열 을 사용하여 단일 테이블을 사용하여 사용자 정의 필드를 정의하십시오 . 그런 다음 각 데이터 유형에 대해 별도의 테이블을 작성하고 해당 테이블 각각에 fieldId 및 데이터 유형 컬럼 별로 색인을 작성하는 색인이 있습니다. 그런 다음 쿼리에서 다음과 같은 것을 사용하십시오.

SELECT *
FROM FieldValues_Text
WHERE fieldId IN (
    SELECT fieldId FROM Fields WHERE userId=@userId
)
AND value LIKE '%' + @search + '%'

이것은 내 생각에 사용자 정의 유형에 대해 최상의 성능을 보장합니다.

필자의 경험에 따르면 매월 수백만 명의 사용자에게 서비스를 제공하고 사용자 지정 제품 특성을 가진 수천 개의 제품을 호스팅하며 데이터베이스는보고를 위해 작업 부하를 쉽게 처리합니다.

보고의 경우 필드 테이블 레이블 값을 열 이름으로 PIVOT변환 한 다음 각 데이터 유형 테이블의 쿼리 결과를 피벗 된 열로 피벗 할 수 있습니다.

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