복붙노트

[SQL] 어떻게 필드 정의 사용자에 대한 데이터베이스를 설계?

SQL

어떻게 필드 정의 사용자에 대한 데이터베이스를 설계?

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

기타 정보:

옵션 :

해결법

  1. ==============================

    1.성능이 주요 관심사 인 경우에, 나는 # 6으로 갈 것 ... UDF 당 표 (정말,이 # 2의 변종이다). 이 응답은 특별히 설명이 상황 데이터 분포의 설명 및 패턴에 맞게 조정된다.

    성능이 주요 관심사 인 경우에, 나는 # 6으로 갈 것 ... UDF 당 표 (정말,이 # 2의 변종이다). 이 응답은 특별히 설명이 상황 데이터 분포의 설명 및 패턴에 맞게 조정된다.

  2. ==============================

    2.나는이 문제에 많은 대해 작성했습니다. 가장 일반적인 해결책은 당신이 당신의 옵션 # 3에서 설명하는 것과 유사한 엔티티 - 속성 - 값 안티 패턴입니다. 전염병 등이 디자인을 피하십시오.

    나는이 문제에 많은 대해 작성했습니다. 가장 일반적인 해결책은 당신이 당신의 옵션 # 3에서 설명하는 것과 유사한 엔티티 - 속성 - 값 안티 패턴입니다. 전염병 등이 디자인을 피하십시오.

    내가 진정으로 동적 사용자 정의 필드를 필요로 할 때 나는이 솔루션을 사용하는 것은 내가 언제든지 새로운 필드를 추가 할 수 있도록, XML의 BLOB에 저장하는 것입니다. 그러나 (- 검색 필드 당 테이블은 필드 당 테이블을하지 않습니다)이 빠른, 또한 검색하거나 정렬 할 필요가 각 필드에 대한 추가 테이블을 생성 할 수 있습니다. 이것은 때때로 반전 인덱스 디자인이라고합니다.

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

    또는 당신이 당신이 문서 당 사용자 정의 필드를 가질 것으로 예상있어 문서 지향 데이터베이스를 사용할 수 있습니다. 나는 SOLR를 선택할 것입니다.

  3. ==============================

    3.나는 아마 다음과 같은 구조의 테이블을 만들 것입니다 :

    나는 아마 다음과 같은 구조의 테이블을 만들 것입니다 :

    물론 정확한 종류는 (그리고 물론 DBMS에서 사용하는) 사용자의 필요에 따라 달라집니다. 또한 INT의 및 부울에 대한 NumberValue (10 진수) 필드를 사용할 수 있습니다. 당신은뿐만 아니라 다른 유형을해야 할 수도 있습니다.

    당신은 값을 자신의 마스터 레코드에 대한 몇 가지 링크가 필요합니다. 각 마스터 테이블에 대한 사용자 필드 테이블을 작성하고 간단한 외래 키를 추가 할 아마도 가장 쉽고 빠른입니다. 당신은 사용자가 마스터 레코드를 필터링 할 수 있습니다이 방법은 쉽고 빠르게 필드.

    당신은 메타 데이터 정보의 어떤 종류를 할 수 있습니다. 당신은 다음과 결국 그래서 :

    표 UdfMetaData

    표 MasterUdfValues

    무슨 일이 있어도, 동적으로 테이블 구조를 변경하지 않을 것입니다. 이것은 유지 보수 악몽이다. 또한 그들은 너무 느리다, XML 구조를 사용하지 않을 것입니다.

  4. ==============================

    4.더 나은 MongoDB를 또는 CouchDB를 같은 비 관계형 솔루션에 의해 해결 될 수있는 문제와 같은이 소리.

    더 나은 MongoDB를 또는 CouchDB를 같은 비 관계형 솔루션에 의해 해결 될 수있는 문제와 같은이 소리.

    당신이 당신이 찾는 튜플의 무결성을 유지하기 위해 허용하고있는 동안 그들은 둘 다 동적 스키마 확장을 할 수 있습니다.

    나는 빌 Karwin과 함께 EAV 모델은 당신을 위해 확대됨에 접근하지 않습니다 동의합니다. 관계형 시스템에서 이름 - 값 쌍을 사용하는 것은 본질적으로 나쁘지는 않지만 이름 - 값 쌍은 정보의 전체 튜플을 경우에만 작동합니다. 를 사용하여 동적으로 실행 시간에 테이블을 재구성하도록 강제하는 경우, 모든 종류의 것들은 발기가 시작합니다. 쿼리는 개체 층에 튜플 재건을 밀어 피벗 유지 보수 또는 힘의 운동이된다.

    당신은 널 또는 누락 된 값이 유효한 항목이 있는지 여부를 확인 또는 개체 층에서 스키마 규칙을 포함시키지 않고 항목의 부족 수 없습니다.

    당신은 효율적으로 스키마를 관리 할 수있는 능력을 잃게됩니다. 100 문자 VARCHAR는 "값"필드에 적합한 유형인가? 200 자? 대신 NVARCHAR해야 하는가? 그것은 하드 트레이드 오프와 당신과 함께 끝이 세트의 역동적 인 자연 장소 인공 한계를 갖는 하나가 될 수 있습니다. 당신은 X 사용자 정의 필드를 가질 수 있고 각각은 긴 Y 자입니다 "와 같은 뭔가.

    문서 중심의 솔루션을 사용하여 MongoDB 또는 CouchDB를 같이, 당신은 하나의 튜플 내에서 사용자와 관련된 모든 속성을 유지한다. 문제가되지 않습니다 조인 때문에이 두 가지 중 어느 것도 과대 광고에도 불구하고, 조인 잘처럼, 생활은 행복하다. 당신이 약 4MB에 도달 할 때까지 관리하기 위해 열심히하지 않는 길이에 그들이 원하는 사용자는 많은 속성으로 정의 할 수 있습니다 (또는 당신이 수).

    당신은 ACID 수준의 무결성을 요구하는 데이터가있는 경우, 당신은 당신의 관계형 데이터베이스에 살고있는 고집적 데이터와 비 관계형 저장소에 살고있는 동적 데이터와, 분할 솔루션 고려할 수 있습니다.

  5. ==============================

    5.사용자 정의 열을 추가 사용자를 제공하더라도, 반드시 그 열을 조회하는 것은 잘 수행하는 경우되지 않습니다. 그 첫 번째 장소에 저장해야하는지에 적절한 사양이 가장 중요한있는 잘 수행 할 수 있도록 쿼리 디자인에 가서 많은 측면이 있습니다. 따라서, 기본적으로, 당신이 사용자가 사양으로 생각하지 않고 스키마를 만들고 해당 스키마에서 빠르게 파생 정보를 할 수 있도록 허용 할 것입니다? 만약 그렇다면, 당신은 사용자가 데이터에 대한 수치 분석을 할 수있게하려면 이러한 솔루션은 특히 확장 성 것 unlikley입니다.

    사용자 정의 열을 추가 사용자를 제공하더라도, 반드시 그 열을 조회하는 것은 잘 수행하는 경우되지 않습니다. 그 첫 번째 장소에 저장해야하는지에 적절한 사양이 가장 중요한있는 잘 수행 할 수 있도록 쿼리 디자인에 가서 많은 측면이 있습니다. 따라서, 기본적으로, 당신이 사용자가 사양으로 생각하지 않고 스키마를 만들고 해당 스키마에서 빠르게 파생 정보를 할 수 있도록 허용 할 것입니다? 만약 그렇다면, 당신은 사용자가 데이터에 대한 수치 분석을 할 수있게하려면 이러한 솔루션은 특히 확장 성 것 unlikley입니다.

    IMO이 방법은 재앙과 보고서 디자이너 악몽 스키마 무엇을 의미하는지에 관한 어떤 지식을 당신에게 스키마를 제공합니다. 즉, 당신은 어떤 데이터를 어떻게 열 저장소를 알 수있는 메타 데이터가 있어야합니다. 메타 데이터가 엉망이 도착하면, 데이터를 호스 가능성이있다. 게다가, 그것은 쉽게 잘못된 열에 잘못된 데이터를 입력 할 수 있습니다. ( "어떻게? 문자열 1은 내가 그것을 가리개가 쉰이 가장 좋아하는 약이라고 생각? 수도원의 이름을 포함합니다.")

    IMO, 요구 사항 2, 3, 4는 EAV의 변화를 제거 할 수 있습니다. 당신이 정렬 쿼리에 필요하거나이 데이터를 계산을 할 경우, 다음 EAV는 크 툴루의 꿈이며, 개발 팀과 DBA의 악몽. EAV의 성능의 측면에서 병목 현상을 생성하고 당신에게 당신이 신속하게 원하는 정보를 얻을 필요가 데이터 무결성을 제공하지 않습니다. 쿼리는 신속하게 고르 디우스의 매듭을 크로스 탭에 켜집니다.

    사양을 수집하고 스키마를 구축 : 그건 정말 하나의 선택을 떠난다.

    클라이언트가 저장하려는 데이터에 대한 최상의 성능을 원하는 경우에, 그들은 그것이 가능한 한 효율적으로 저장되도록 자신의 요구 사항을 이해하기 위해 개발자와 협력의 과정을 통해 이동해야합니다. 여전히 동적으로 테이블의 스키마를 기반으로 양식을 구축하는 것이 코드 테이블의 나머지는 별도의 테이블에 저장 될 수있다. 당신이 열을 확장 속성 수있는 데이터베이스가있는 경우, 당신도 필요하다고 모든 스키마를 추가하는 것입니다 너무 툴팁 등 양식 빌더를 사용 좋은 레이블을 돕기 위해 사람들을 사용할 수 있습니다. 어느 쪽이든, 효율적으로 구축 및 실행 보고서, 데이터 요구가 제대로 저장합니다. 해당 데이터가 널 많이 있습니다 경우, 일부 데이터베이스는 정보의 유형을 저장할 수있는 기능이 있습니다. 예를 들어, SQL 서버 2008은 널 (null)이 많은 데이터를 스파 스 열 특별히라는 기능이 있습니다.

    이 더 분석, 필터링하지 않거나 할 수 있었다 정렬 된 데이터의 가방이라면, 나는 EAV의 몇 가지 변화가 트릭을 할 수 말할 것입니다. 그러나, 요구 사항 주어진 가장 효율적인 솔루션은 해당 테이블 떨어져 동적으로 별도의 테이블과 빌드 형태로 이러한 새 열을 저장하는 경우에도 적절한 사양을 얻을 수있을 것입니다.

    스파 스 열

  6. ==============================

    6.데이터 유형에 따라 내 연구 여러 테이블에 따라 성능에 도움이하지 않을. 당신은 50 개 이상의 UDF를 가진 20K 나 25K 기록과 같은 대량의 데이터를 가지고 특히합니다. 성능은 최악이었다.

    데이터 유형에 따라 내 연구 여러 테이블에 따라 성능에 도움이하지 않을. 당신은 50 개 이상의 UDF를 가진 20K 나 25K 기록과 같은 대량의 데이터를 가지고 특히합니다. 성능은 최악이었다.

    당신과 같은 여러 열이 하나의 테이블로 가야한다 :

    varchar Name
    varchar Type
    decimal NumberValue
    varchar StringValue
    date DateValue
    
  7. ==============================

    7.이것은 문제가있는 상황이며, 해결책으로는 "오른쪽"표시되지 않습니다. 그러나 옵션 1은 단순 측면과 성능면에서 모두 아마 최고입니다.

    이것은 문제가있는 상황이며, 해결책으로는 "오른쪽"표시되지 않습니다. 그러나 옵션 1은 단순 측면과 성능면에서 모두 아마 최고입니다.

    이것은 또한 일부 상용 엔터프라이즈 애플리케이션에 사용되는 솔루션입니다.

    편집하다

    구할 수 있지만 문제는 질문 원래 때 존재하지 않았다 (또는 적어도 성숙되지 않은) 또 다른 옵션은 DB의 필드를 JSON 사용하는 것입니다.

    많은 관계형 DB를 이제 JSON 기반 필드 (즉, 서브 필드의 동적 목록을 포함 할 수있다)과 그들에 쿼리 수 있도록 지원

    포스트 그레스

    MySQL은

  8. ==============================

    8.나는 그것이 데이터가 나 정말 기록의 동적 유형에 아래로 데이터를 깰 부드러운 분류 일종의 복잡 분명한되지 않는으로, 하나 지저분한까지 경험이나 1, 3, 4, 그들은 모두 말을 했어.

    나는 그것이 데이터가 나 정말 기록의 동적 유형에 아래로 데이터를 깰 부드러운 분류 일종의 복잡 분명한되지 않는으로, 하나 지저분한까지 경험이나 1, 3, 4, 그들은 모두 말을 했어.

    당신은 UDF 데이터의 차이 세트를 잡고 도움이 될 것입니다 입력 등 데이터를 확인하기 위해 XML의 내용에 대해 스키마를 시행 할 수 있어야한다, XML을 시도하는 유혹 것입니다. SQL 서버의 최신 버전에서는 XML 필드 인덱스는 성능에 도움을해야 할 수있다. (예 http://blogs.technet.com/b/josebda/archive/2009/03/23/sql-server-2008-xml-indexing.aspx 참조)

  9. ==============================

    9.당신은 SQL 서버를 사용하는 경우를 SqlVariant 유형을 간과하지 않습니다. 그것은 꽤 빨리 당신의 일을해야한다. 다른 데이터베이스는 비슷한있을 수 있습니다.

    당신은 SQL 서버를 사용하는 경우를 SqlVariant 유형을 간과하지 않습니다. 그것은 꽤 빨리 당신의 일을해야한다. 다른 데이터베이스는 비슷한있을 수 있습니다.

    XML 데이터 유형은 성능상의 이유로 그렇게 잘되지 않습니다. 개봉 서버에서 계산을하는 경우에 당신은 지속적으로 이러한 직렬화 할 필요가 있습니다.

    옵션 1 개 나쁜 소리와 cruddy 보이지만, 성능 현명한 당신의 최선의 방법이 될 수 있습니다. 나는 당신이 단지 성능을 이길 수 없기 때문에 전에 Field00-Field99라는 이름의 열이있는 테이블을 만들었습니다. 이 또한 갈 수있는 하나이 경우 너무 당신의 INSERT 성능을 고려할 필요가 있습니다. 당신이 깔끔한보고 싶은 경우에 당신은 항상이 테이블에 뷰를 만들 수 있습니다!

  10. ==============================

    10.셰어 옵션 1을 사용하고, 합리적인 성능을 가지고있다.

    셰어 옵션 1을 사용하고, 합리적인 성능을 가지고있다.

  11. ==============================

    11.나는 이러한 옵션 (옵션 6? :))을 전혀 사용하지 않는 과거에 매우 성공적으로 관리했습니다.

    나는 이러한 옵션 (옵션 6? :))을 전혀 사용하지 않는 과거에 매우 성공적으로 관리했습니다.

    나는 사용자가 (XML로 저장 및 사용자 정의 모델링 도구를 통해 노출)를 재생하고 모델 생성 된 테이블과 뷰에서 사용자 정의 데이터 테이블이 기본 테이블에 가입 할 수있는 모델을 만들 수 있습니다. 각 유형은 핵심 데이터 및 사용자 정의 필드와 사용자 테이블이있는 기본 테이블을 것 그래서.

    예를 들어 문서를 가지고 : 일반적인 필드는이 핵심 테이블에 갈 것 등의 이름, 유형, 날짜, 저자가 될 것입니다. 그런 다음 사용자는 CONTRACT_END_DATE, renewal_clause, ㅋ ㅋ ㅋ ㅋ ㅋ ㅋ 등 자신의 분야와 함께 자신의 특별한 문서 유형을 정의합니다. 해당 사용자 정의 된 문서를위한 공통 기본 키 접합 코어 문서 테이블은 xcontract 테이블있을 것이다합니다 (xcontracts 있도록 일차 키는 또한 코어 테이블의 기본 키에 외래 인). 그럼이 두 테이블을 래핑하는 뷰를 생성합니다. 쿼리 성능이 빨랐다. 추가 비즈니스 규칙은 또한 뷰에 포함 할 수 있습니다. 이것은 나를 위해 정말 잘했다.

  12. ==============================

    12.사용자가 이상 7K "사용자 정의 필드"가 우리의 데이터베이스에 전력 SaaS는 응용 프로그램 (헬프 데스크 소프트웨어). 우리는 결합 방법을 사용 :

    사용자가 이상 7K "사용자 정의 필드"가 우리의 데이터베이스에 전력 SaaS는 응용 프로그램 (헬프 데스크 소프트웨어). 우리는 결합 방법을 사용 :

    또한 귀하는,이 대답은 제안처럼 "데이터 형식에 따라 표"를 가지고 당신도 색인 UDF를 할 수있는이 방법을 # 1을 분할 할 수있다.

    추신 단어의 커플은 "엔티티 - 속성 - 값"접근 방식 모두가 학대를 유지 방어. 우리는 수십 년 동안 # 2없이 # 1을 사용하고 그냥 벌금을했다. 때로는 비즈니스 의사 결정이다. 당신은 당신의 응용 프로그램을 다시 작성하고 DB를 재 설계하는 시간이 마십시오 당신은 정말 저렴 요즘입니다 클라우드 서버 달러, 몇 던질 수 있습니까? 그런데, 우리는 # 1 방법을 사용했을 때, 우리의 DB는 사용자의 수천의 수백에 의해 액세스, 엔티티의 수백만을 유지하고, 16 기가 바이트 듀얼 코어 DB 서버가 잘 일이었다

  13. ==============================

    13.코멘트에서 나는 UDF 필드가 제대로 사용자가 매핑되지 않은 가져온 데이터를 덤프 있다는 말을 보았다.

    코멘트에서 나는 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 풋 프린트 작은 만들지 만, 응용 프로그램 더 복잡합니다.

  14. ==============================

    14.나는 매우 공인 전자 상거래 CMS 플랫폼입니다 젠토에 사용 된 이러한 유형의 시스템 때문에 # 4를 추천 할 것입니다. fieldID가 및 라벨 열을 사용하여 사용자 정의 필드를 정의하는 하나의 테이블을 사용합니다. 그 후, 각각의 데이터 유형에 대한 별도의 테이블을 가지고 그 테이블의 각각의 인덱스가 그 안에 fieldID가 데이터 타입 값에 의해 인덱스 컬럼. 그런 다음 쿼리에서, 같은 것을 사용 :

    나는 매우 공인 전자 상거래 CMS 플랫폼입니다 젠토에 사용 된 이러한 유형의 시스템 때문에 # 4를 추천 할 것입니다. fieldID가 및 라벨 열을 사용하여 사용자 정의 필드를 정의하는 하나의 테이블을 사용합니다. 그 후, 각각의 데이터 유형에 대한 별도의 테이블을 가지고 그 테이블의 각각의 인덱스가 그 안에 fieldID가 데이터 타입 값에 의해 인덱스 컬럼. 그런 다음 쿼리에서, 같은 것을 사용 :

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

    이것은 내 의견으로는 사용자 정의 유형에 대한 최상의 성능을 보장합니다.

    내 경험에 의하면, 나는 한 달에 수백만의 사용자를 제공 여러 젠토 웹 사이트, 사용자 정의 제품 속성을 가진 제품의 호스트 수천에 근무했습니다, 데이터베이스 핸들 워크로드를 쉽게도보고.

    보고를 들어, 당신은 그 피벗 열에 각 데이터 유형 테이블에서 쿼리 결과를 한 후, 열 이름으로 필드 테이블 라벨 값을 변환 피벗 PIVOT을 사용할 수 있습니다.

  15. from https://stackoverflow.com/questions/5106335/how-to-design-a-database-for-user-defined-fields by cc-by-sa and MIT license