คุณจะออกแบบฐานข้อมูลผู้ใช้ด้วยฟิลด์ที่กำหนดเองได้อย่างไร


18

คำถามนี้เกี่ยวกับวิธีที่ฉันควรออกแบบฐานข้อมูลมันอาจเป็นฐานข้อมูลเชิงสัมพันธ์ / nosql ขึ้นอยู่กับสิ่งที่จะเป็นทางออกที่ดีกว่า


กำหนดข้อกำหนดที่คุณจะต้องสร้างระบบที่จะเกี่ยวข้องกับฐานข้อมูลเพื่อติดตาม "บริษัท " และ "ผู้ใช้" ผู้ใช้คนเดียวเป็นของ บริษัท เดียวเสมอ

  • ผู้ใช้สามารถเป็นของ บริษัท เดียวเท่านั้น
  • บริษัท สามารถมีผู้ใช้หลายคน

การออกแบบสำหรับตาราง "บริษัท " ค่อนข้างตรงไปตรงมา บริษัท จะมีคุณสมบัติ / คอลัมน์ต่อไปนี้: (ขอให้ง่าย)

ID, COMPANY_NAME, CREATED_ON

สถานการณ์แรก

เรียบง่ายและตรงไปตรงมาผู้ใช้ทุกคนมีคุณลักษณะเดียวกันดังนั้นสิ่งนี้สามารถทำได้อย่างง่ายดายในลักษณะสัมพันธ์ตารางผู้ใช้:

ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CREATED_ON

สถานการณ์ที่สอง

จะเกิดอะไรขึ้นหาก บริษัท ต่าง ๆ ต้องการจัดเก็บแอตทริบิวต์โปรไฟล์ที่แตกต่างกันสำหรับผู้ใช้ แต่ละ บริษัท จะมีชุดแอตทริบิวต์ที่กำหนดไว้ซึ่งจะใช้กับผู้ใช้ทั้งหมดของ บริษัท นั้น

ตัวอย่างเช่น:

  • บริษัท A ต้องการเก็บ: LIKE_MOVIE (บูลีน), LIKE_MUSIC (บูลีน)
  • บริษัท B ต้องการเก็บ: FAV_CUISINE (สตริง)
  • บริษัท C ต้องการเก็บ: OWN_DOG (บูลีน), DOG_COUNT (int)

วิธีที่ 1

วิธีเดรัจฉานบังคับคือการมี schema เดียวสำหรับผู้ใช้และให้พวกเขามีโมฆะเมื่อพวกเขาไม่ได้เป็นของ บริษัท :

ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, LIKE_MOVIE, LIKE_MUSIC, FAV_CUISINE, OWN_DOG, DOG_COUNT, CREATED_ON

ซึ่งน่ารังเกียจเพราะคุณจะจบลงด้วยจำนวน NULLS และแถวผู้ใช้ที่มีคอลัมน์ที่ไม่เกี่ยวข้อง (เช่นผู้ใช้ทั้งหมดที่เป็นของ บริษัท A มีค่า NULL สำหรับ FAV_CUISINE, OWN_DOG, DOG_COUNT)

วิธีที่ 2

วิธีที่สองคือต้องมี "เขตข้อมูลอิสระ":

ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_1, CUSTOM_2, CUSTOM_3, CREATED_ON

ซึ่งน่ารังเกียจด้วยตัวเองเนื่องจากคุณไม่ทราบว่าฟิลด์ที่กำหนดเองคืออะไรประเภทข้อมูลจะไม่สะท้อนค่าที่จัดเก็บ (เช่นเราจะเก็บค่า int เป็น VARCHAR)

วิธีที่ 3

ฉันได้ดูในฟิลด์ PostgreSQL JSON ซึ่งในกรณีนี้คุณจะมี:

ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_PROFILE_JSON, CREATED_ON

ในกรณีนี้คุณจะสามารถใช้สคีมาที่แตกต่างกับผู้ใช้ได้อย่างไร ผู้ใช้ที่มี Company A จะมีสคีมาที่ดูเหมือน

 {"LIKE_MOVIE":"boolean", "LIKE_MUSIC": "boolean"}

ในขณะที่ผู้ใช้ที่มี Company C จะมีสคีมาต่างกัน:

 {"OWN_DOG ":"boolean", "DOG_COUNT": "int"}

ฉันจะแก้ไขปัญหานี้ได้อย่างไร ฉันจะออกแบบฐานข้อมูลอย่างถูกต้องเพื่อให้สคีมาที่ยืดหยุ่นนี้สำหรับ "วัตถุ" เดียว (ผู้ใช้) ตามความสัมพันธ์ที่มี (บริษัท ) ได้อย่างไร

วิธีการแก้ปัญหาเชิงสัมพันธ์? วิธีการแก้ปัญหา nosql?


แก้ไข:ฉันยังคิดถึงตาราง "CUSTOM_PROFILE" ซึ่งจะเก็บแอตทริบิวต์ของผู้ใช้ในแถวแทนที่จะเป็นคอลัมน์

มี 2 ​​ปัญหาเกี่ยวกับวิธีการนี้:

1) ข้อมูลเติบโตต่อผู้ใช้ที่เติบโตเป็นแถวแทนที่จะเป็นคอลัมน์ - และนี่หมายถึงการได้รับภาพเต็มของผู้ใช้จำเป็นต้องทำการรวมจำนวนมากเข้าร่วมหลายตารางกับ "โปรไฟล์ที่กำหนดเอง" ในแอตทริบิวต์ที่กำหนดเองที่แตกต่างกัน

2) ค่าข้อมูลจะถูกเก็บเป็น VARCHAR ให้เป็นค่าทั่วไปเสมอแม้ว่าเราจะทราบว่าข้อมูลนั้นควรเป็นจำนวนเต็มหรือบูลีนเป็นต้น


3
หาก บริษัท ที่แตกต่างกันมีชุดข้อมูลหลายค่าที่แตกต่างกันสำหรับลูกค้าแต่ละรายคุณต้องมีตารางการเชื่อมโยง COMPANY_CUSTOMER ทุกอย่างอื่นจะทำให้คุณเจ็บปวดอย่างมากในไม่ช้า
Kilian Foth

ตารางการลิงก์จะช่วยอย่างไรกับข้อมูลที่กำหนดเองได้อย่างไร คอลัมน์จะต้องมีความแตกต่าง
noobcser

1
คุณต้องแสดงให้เห็นถึงความจริง "รหัสผ่านของ Kilian สำหรับ IKEA คือ 'ลูกแมว' 'ที่มี tuple เช่น" บริษัท : IKEA ลูกค้า: Kilian, คุณสมบัติ: รหัสผ่าน, ค่า: ลูกแมว " อะไรที่เรียบง่ายกว่าจะไม่ทำงาน
Kilian Foth

3
สคีมาเป็นสิ่งที่คงที่ตามคำนิยาม; คุณไม่สามารถตั้งค่าได้ถ้าคุณไม่รู้ว่าคุณต้องการอะไร ลองดูที่Entity-Attribute-Valueเพื่อหาปัญหาทางเดียวเช่นนี้มักจะได้รับการแก้ไขในฐานข้อมูลเชิงสัมพันธ์
Mason Wheeler

คำตอบ:


13

โปรดพิจารณาสิ่งนี้เป็นทางเลือก ตัวอย่างสองตัวอย่างก่อนหน้านี้ทั้งสองต้องการให้คุณทำการเปลี่ยนแปลง schema เนื่องจากขอบเขตของแอปพลิเคชันเพิ่มขึ้นนอกจากนี้โซลูชัน "custom_column" นั้นยากต่อการขยายและบำรุงรักษา ในที่สุดคุณจะได้รับ Custom_510 จากนั้นลองจินตนาการว่าตารางนี้จะทำงานได้ดีเพียงใด

ขั้นแรกให้ใช้โครงสร้าง บริษัท ของคุณ

[Companies] ComnpanyId, COMPANY_NAME, CREATED_ON

ต่อไปเราจะใช้สคีมาผู้ใช้ของคุณสำหรับแอตทริบิวต์ที่จำเป็นในระดับสูงสุดที่ทุก บริษัท จะใช้ / แชร์

[Users] UserId, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CREATED_ON

ต่อไปเราจะสร้างตารางที่เราจะกำหนดแอตทริบิวต์แบบไดนามิกของเราที่เฉพาะเจาะจงสำหรับแต่ละคุณสมบัติของผู้ใช้ที่กำหนดเอง ดังนั้นที่นี่ค่าตัวอย่างของคอลัมน์แอตทริบิวต์จะเป็น "LikeMusic":

[UserAttributeDefinition] UserAttributeDefinitionId, CompanyId, Attribute

ต่อไปเราจะกำหนดตาราง UserAttributes ที่จะเก็บค่าคุณสมบัติผู้ใช้

[UserAttributes] UserAttributeDefinitionId, UserId, Value

สิ่งนี้สามารถแก้ไขได้หลายวิธีเพื่อประสิทธิภาพที่ดีขึ้น คุณสามารถใช้หลายตารางสำหรับ UserAttributes ทำให้แต่ละชนิดที่เฉพาะเจาะจงกับข้อมูลที่ถูกเก็บไว้ในค่าหรือเพียงแค่ปล่อยให้มันเป็น VarChar และทำงานกับมันเป็นที่เก็บคีย์ค่า

คุณอาจต้องการย้าย CompanyId ออกจากตาราง UserAttributeDefiniton และลงในตารางการอ้างอิงโยงสำหรับการพิสูจน์อักษรในอนาคต


ขอบคุณ - ฉันคิดว่าเกี่ยวกับวิธีการดังกล่าวโปรดดูการแก้ไข 2 ปัญหา: 1) ข้อมูลเติบโตขึ้นเป็นแถวซึ่งหมายถึงการรับภาพเต็มของผู้ใช้คุณจะต้องเข้าร่วมจำนวนมาก 2) "value" จะถูกเก็บไว้เป็น VARCHAR เพื่อเป็นค่าทั่วไปแม้ว่าค่านั้นจะเป็น int หรือบูลีนจริง ๆ
ก็ตาม

1
หากคุณใช้ int / bigint สำหรับตัวตนของตารางและเข้าร่วมกับผู้ที่คุณไม่เคยมีปัญหาด้านประสิทธิภาพใด ๆ จนกว่าคุณจะมีจำนวนแถวมาก ตอนนี้ถ้าคุณเริ่มค้นหาตามค่าของคุณลักษณะสิ่งนี้อาจทำให้เกิดปัญหาได้ถ้าคุณเริ่มได้รับข้อมูลจำนวนมาก ในกรณีนี้ฉันจะทำงานร่วมกับ DBA เพื่อตรวจสอบว่ามีดัชนีที่สามารถสร้างขึ้นหรืออาจเป็นมุมมองที่จัดทำดัชนีซึ่งสามารถเพิ่มความเร็วในการค้นหาประเภทนี้ได้ ฉันใช้สคีมาที่คล้ายกันและใช้เวลา 100 ล้านรายการต่อปีโดยไม่มีปัญหาด้านประสิทธิภาพใด ๆ ดังนั้นการออกแบบฐานจึงใช้งานได้ดี IMO
P. Roe

หากการรายงานต้องการการกรองการสืบค้นและแอตทริบิวต์ที่แตกต่างกันอาจเป็นของชุดข้อมูลที่แตกต่างกัน วิธีนี้จะดีกว่า NoSQL หรือไม่ ฉันพยายามเข้าใจความแตกต่างด้านประสิทธิภาพ สถานการณ์ที่คล้ายกันผู้ใช้เท่านั้นที่สามารถกำหนดรายงานที่มีฟิลด์ที่ผู้ใช้กำหนด
kos

ในวิธีการข้างต้นเราจะใช้สิ่งที่ค้นหาอย่างไรต่างกันอย่างไร บริษัท ต้องการค้นหาในสาขาของตนรวมถึงสาขาของผู้ใช้ด้วย วิธีที่ถูกต้องในการให้บริการการค้นหาที่ปรับขนาดได้ด้านบนนี้คืออะไร
techagrammer

คุณสามารถค้นหาได้ตามปกติด้วยการเข้าร่วมจำนวนมาก คุณสามารถใช้สคริปต์ ETL เพื่อดึงข้อมูลที่คุณต้องการค้นหาและวางไว้ในโครงสร้างที่มีความผิดปกติมากขึ้น สุดท้ายคุณสามารถพยายามใช้มุมมองที่จัดทำดัชนีเป็นวิธีการค้นหา ส่วนตัวผมแนะนำวิธี ETL เพื่อสร้างโครงสร้าง denormalized ที่ง่ายต่อการค้นหา
P. Roe

7

ใช้ฐานข้อมูล NoSQL จะมีเอกสารของ บริษัท และผู้ใช้ ผู้ใช้จะมีส่วนหนึ่งของสคีมาที่สร้างขึ้นแบบไดนามิกโดยยึดตามเทมเพลตผู้ใช้ (ข้อความเพื่อระบุฟิลด์ / ประเภทของ บริษัท นั้น

\Company\<uniqueidentifier>
    - Name: <Name>
    - CreatedOn: <datetime>
    - UserTemplate: <Text>

\User\<uniqueidentifier>
    - COMPANY_ID: <ID>
    - FIRST_NAME: <Text>
    - LAST_NAME: <Text>
    - EMAIL: <Text>
    - CREATED_ON: <datetime>
    - * Dynamically created fields per company

นี่คือลักษณะที่อาจมีลักษณะเหมือนFirebase.comคุณจะต้องเรียนรู้วิธีการทำในสิ่งที่คุณเลือก


นี่คือสิ่งที่ฉันคิดเกี่ยวกับหรืออาจคอลัมน์ JSON ประสิทธิภาพของการสอบถามการกรองการรายงานเปรียบเทียบกับโซลูชันที่ PRoe เสนอ
kos

1
เมื่อใดก็ตามที่คุณบีบอัดข้อมูลลงใน json หรือ xml แล้วโยนลงในคอลัมน์มันจะช้ามากในการค้นหา หากคุณต้องการค้นหาข้อมูลที่นำเสนอในคำตอบของฉันด้านบนฉันจะแนะนำให้ใช้มุมมองที่จัดทำดัชนีเพื่อดึงข้อมูล หากโซลูชันนั้นไม่เหมาะฉันแนะนำให้ใช้ ETL เพื่อคัดลอกข้อมูลลงในโครงสร้างที่สามารถค้นหาและรายงานได้อย่างง่ายดาย
P. Roe

ในวิธีการข้างต้นเราจะใช้สิ่งที่ค้นหาอย่างไรต่างกันอย่างไร บริษัท ต้องการค้นหาในสาขาของตนรวมถึงสาขาของผู้ใช้ด้วย วิธีที่ถูกต้องในการให้บริการการค้นหาที่ปรับขนาดได้ด้านบนนี้คืออะไร
techagrammer

ในฐานข้อมูล nosql คุณอาจมีข้อมูลซ้ำซ้อน แต่มีโครงสร้างเพื่อให้สามารถค้นหาได้ สิ่งที่แสดงข้างต้นคือตัวระบุที่ไม่ซ้ำกัน อาจมีอีกชื่อหนึ่ง \ ชื่อ บริษัท \ มันคล้ายกับมีหลายดัชนี
JeffO

3

หากคุณมักจะพบกับคำขอฟิลด์ที่กำหนดเองฉันจะทำแบบจำลองนั้นคล้ายกับฐานข้อมูล สร้างตารางที่เก็บข้อมูลเมตาเกี่ยวกับแต่ละฟิลด์ที่กำหนดเอง, CompanyCustomField (ที่เป็นเจ้าของ, ชนิดข้อมูล, ฯลฯ ) และอีกตารางหนึ่ง CompanyCustomFieldValues ​​ซึ่งมี CustomerId, FieldId และค่า หากคุณใช้บางอย่างเช่น Microsoft SQL Server ฉันต้องการให้คอลัมน์ค่าเป็นประเภทข้อมูล sql_variant

แน่นอนว่าไม่ใช่เรื่องง่ายเนื่องจากคุณจะต้องมีอินเทอร์เฟซที่ช่วยให้ผู้ดูแลระบบกำหนดฟิลด์ที่กำหนดเองสำหรับลูกค้าแต่ละรายและอินเทอร์เฟซอื่นที่ใช้ข้อมูลเมตานี้เพื่อสร้าง UI เพื่อรวบรวมค่าฟิลด์ และหากคุณมีข้อกำหนดอื่น ๆ เช่นการจัดกลุ่มเขตข้อมูลร่วมกันหรือจำเป็นต้องทำรายการเลือกประเภทของเขตข้อมูลคุณจะต้องรองรับว่ามีข้อมูลเมตา / ตารางอื่น ๆ เพิ่มเติม (เช่น CompanyCustomFieldPickListOptions)

นี่ไม่ใช่เรื่องเล็กน้อย แต่มีข้อได้เปรียบที่ไม่ต้องการเปลี่ยนแปลงฐานข้อมูล / การเปลี่ยนรหัสสำหรับทุกฟิลด์ที่กำหนดเองใหม่ คุณสมบัติอื่น ๆ ของเขตข้อมูลที่กำหนดเองจะต้องมีการเข้ารหัสเช่นกัน (ตัวอย่างเช่นหากคุณต้องการตรวจสอบความถูกต้องของค่าสตริงใหม่หรืออนุญาตเฉพาะวันที่ระหว่างช่วงที่กำหนดหรือถ้าคุณต้องการเปิดใช้งานฟิลด์ที่กำหนดเองหนึ่งรายการ )


ขอบคุณ - ฉันคิดว่าเกี่ยวกับวิธีการดังกล่าวโปรดดูการแก้ไข 2 ปัญหา: 1) ข้อมูลเติบโตขึ้นเป็นแถวซึ่งหมายถึงการรับภาพเต็มของผู้ใช้คุณจะต้องเข้าร่วมจำนวนมาก 2) "value" จะถูกเก็บไว้เป็น VARCHAR เพื่อเป็นค่าทั่วไปแม้ว่าค่านั้นจะเป็น int หรือบูลีนจริง ๆ
ก็ตาม

1
@ noobcser ข้อมูลที่เพิ่มขึ้นตามแถวไม่สำคัญจริงๆหลังจากฐานข้อมูลทั้งหมดกำลังออกแบบแถวและรวม ไม่ว่าในกรณีใดก็ตามคุณมีแนวโน้มที่จะใช้ Common Table Expressions สำหรับสิ่งนี้ซึ่งค่อนข้างดีในเรื่องแบบนี้ ฉันไม่แน่ใจว่าคุณพลาดส่วนที่ฉันบอกหรือไม่ว่าคุณสามารถใช้ sql_variant เป็นประเภทข้อมูลสำหรับคอลัมน์ค่าซึ่งจะเก็บค่าตามประเภทที่คุณติดอยู่ ในขณะที่ฉันตั้งชื่อชื่อเซิร์ฟเวอร์ MS SQL ฉันคาดหวังว่า DBMS ที่เป็นผู้ใหญ่อื่น ๆ จะมีคุณสมบัติที่คล้ายกัน
Andy

1
@noobcser FYI ฉันได้พบกับข้อกำหนดเหล่านี้ค่อนข้างบ่อยในอาชีพการงานของฉันและมีประสบการณ์กับโซลูชั่นที่เสนอมาแต่ละข้อดังนั้นฉันจึงแนะนำสิ่งที่ได้ผลดีที่สุดในประสบการณ์ของฉัน การใช้ชนิดข้อมูล xml สำหรับสิ่งนี้เป็นเพียงบางส่วนทำไมฉันเกลียดที่ MS เพิ่ม xml เป็นชนิดข้อมูลดั้งเดิม
Andy

1

อีกทางเลือกหนึ่งสำหรับคำตอบอื่น ๆ คือให้มีตารางชื่อ profile_attrib หรือคล้ายกันว่าแอปพลิเคชันของคุณมีการจัดการสคีมาอย่างสมบูรณ์

เมื่อเพิ่มแอตทริบิวต์ที่กำหนดเองALTER TABLE profile_attrib ADD COLUMN like_movie TINYINT(1)แล้วคุณสามารถห้ามลบได้ วิธีนี้จะลดการเข้าร่วมของคุณในขณะที่ยังให้ความยืดหยุ่น

ฉันเดาว่าการแลกเปลี่ยนบิตคือแอปพลิเคชั่นต้องการเปลี่ยนสิทธิ์ของตารางในฐานข้อมูลและคุณต้องฉลาดเกี่ยวกับการทำให้ชื่อคอลัมน์สะอาด


การแสดงออกปกติ[^\w-]+น่าจะทำได้ดีไม่อนุญาตให้ทำสิ่งที่ไม่ใช่0-9A-Za-z_-- แต่ใช่การฆ่าเชื้อเป็นสิ่งที่ต้องทำที่นี่เพื่อป้องกันอันตรายหรือความโง่เขลา
ปกติ Joe

0

คำถามของคุณมีวิธีแก้ไขที่เป็นไปได้มากมาย ทางออกหนึ่งคือการจัดเก็บ attribrutes เพิ่มเติมเป็น XML XML สามารถจัดเก็บเป็นข้อความหรือหากคุณใช้ฐานข้อมูลที่สนับสนุนประเภท XML เป็น XML (SQL Server) การจัดเก็บเป็นข้อความจะจำกัดความสามารถในการสืบค้นของคุณ (เช่นการค้นหาในแอตทริบิวต์ที่กำหนดเอง) แต่ถ้าการจัดเก็บและดึงข้อมูลเป็นสิ่งที่คุณต้องการ หากจำเป็นต้องสอบถามแล้วการจัดเก็บ XML เป็นประเภท XML จะเป็นตัวเลือกที่ดีกว่า

สิ่งนี้จะให้ความสามารถอย่างหนึ่งในการจัดเก็บแอตทริบิวต์จำนวนเท่าใดก็ได้ให้กับลูกค้าเพียงแค่เพิ่มคอลัมน์เพิ่มเติมในตารางลูกค้า หนึ่งสามารถจัดเก็บคุณลักษณะเป็น hashset หรือพจนานุกรมหนึ่งจะสูญเสียความปลอดภัยของประเภทเนื่องจากทุกอย่างจะเป็นสตริงที่จะเริ่มต้นด้วย แต่ถ้าใครบังคับใช้สตริงรูปแบบมาตรฐานสำหรับวันที่ตัวเลขบูลีนก็จะตกลง

สำหรับข้อมูลเพิ่มเติม:

https://msdn.microsoft.com/en-us/library/hh403385.aspx

@ WalterMitty คำตอบนั้นถูกต้องเช่นกันถึงแม้ว่าหากมีลูกค้าจำนวนมากที่มีคุณลักษณะที่แตกต่างกันก็สามารถจบลงด้วยตารางจำนวนมากหากติดตามโมเดลการสืบทอด ขึ้นอยู่กับจำนวนแอตทริบิวต์ที่กำหนดเองที่ใช้ร่วมกันระหว่างลูกค้า


สิ่งนี้สามารถทำงานได้เช่นกัน แต่ฉันรู้สึกว่า จำกัด เมื่อคุณต้องทำอะไรบางอย่างกับข้อมูลที่เก็บไว้ในฟิลด์ XML / JSON
Andy

@Andy - จริงมีอีกชั้นหนึ่ง Query DB และแยกวิเคราะห์ XML ซึ่งตรงข้ามกับการสืบค้น DB ฉันไม่รู้ว่าฉันจะเรียกมันว่า จำกัด แค่ยุ่งยากขึ้นหรือเปล่า แต่จะมีบางอย่างที่ต้องพิจารณาหากมีการใช้แอตทริบิวต์ที่กำหนดเองอย่างกว้างขวาง
Jon Raynor

ใน T-SQL เป็นไปได้ที่จะกำหนดเนื้อหาในคอลัมน์ XML / JSON เทียบกับเนมสเปซและแบบสอบถามกับองค์ประกอบในข้อมูลที่กำหนดเอง ไม่ใช่เรื่องยาก
สตีเฟ่นยอร์

-1

คุณควรทำให้ฐานข้อมูลของคุณเป็นปกติเช่นคุณมี 3 ตารางที่แตกต่างกันสำหรับโปรไฟล์ บริษัท แต่ละประเภท ใช้ตัวอย่างของคุณคุณจะมีตารางที่มีคอลัมน์:

USER_ID, LIKE_MOVIE, LIKE_MUSIC

USER_ID, FAVORITE_CUISINE

USER_ID, OWN_DOG, DOG_COUNT

วิธีนี้ถือว่าคุณจะรู้ถึงรูปร่างของข้อมูลที่ บริษัท ต้องการจัดเก็บไว้ก่อนมือและมันจะไม่เปลี่ยนแปลงบ่อยนัก หากรูปร่างของข้อมูลไม่เป็นที่รู้จักในขณะออกแบบอาจเป็นการดีกว่าถ้าจะไปกับฟิลด์ JSON นั้นหรือฐานข้อมูล nosql


-1

ไม่ว่าจะด้วยเหตุผลใดก็ตามฐานข้อมูลเป็นฟิลด์หนึ่งที่เอฟเฟกต์แพลตฟอร์มด้านในปรากฏบ่อยที่สุด นี่เป็นเพียงอีกกรณีหนึ่งของการต่อต้านแบบผุดขึ้น

ในกรณีนี้คุณกำลังพยายามต่อสู้กับวิธีที่ถูกต้องและเป็นธรรมชาติ ผู้ใช้ของ บริษัท A ไม่ใช่ผู้ใช้ของ บริษัท B และพวกเขาควรมีตารางของตนเองสำหรับฟิลด์ของตนเอง

ผู้ขายฐานข้อมูลของคุณไม่คิดค่าใช้จ่ายจากตารางและคุณไม่ต้องการพื้นที่ดิสก์สองเท่าสำหรับตารางสองเท่า (อันที่จริงแล้วการมีสองตารางมีประสิทธิภาพมากกว่าเพราะคุณไม่ได้จัดเก็บแอตทริบิวต์ของ A สำหรับผู้ใช้ของ B ใช้พื้นที่)

แน่นอนถ้ามีเขตข้อมูลทั่วไปที่เพียงพอคุณสามารถแยกเขตข้อมูลเหล่านั้นออกเป็นตารางผู้ใช้ที่ใช้ร่วมกันและมีรหัสต่างประเทศในแต่ละตารางผู้ใช้เฉพาะ บริษัท นี่เป็นโครงสร้างอย่างง่ายที่ไม่มีเครื่องมือเพิ่มประสิทธิภาพการสืบค้นฐานข้อมูลต่อสู้กับมัน เข้าร่วมใด ๆ ที่จำเป็นเล็กน้อย


3
และหากคุณมีลูกค้าหลายพันรายต่อตารางสามารถกลายเป็นสิ่งที่ไม่อาจปฏิเสธได้อย่างรวดเร็วไม่ต้องพูดถึงว่าคุณจะต้องใช้รหัสที่กำหนดเองสำหรับเขตข้อมูลที่กำหนดเองของลูกค้าแต่ละราย
Andy

@Andy: เดาอะไร สถานการณ์จะยิ่งไม่อาจทำลายได้ถ้าคุณผสมผสานรูปแบบที่แตกต่างกันหลายพันแผนให้เป็นตารางเดียว และใช่คุณอาจต้องใช้รหัสที่กำหนดเองสำหรับฟิลด์ที่กำหนดเอง อีกครั้งที่ง่ายกว่าไม่ใช่ยากขึ้นหากลูกค้าแต่ละรายมีตารางแยกกัน การพยายามเลือกสาขาของ บริษัท X จากคนอื่นอีกพันคนนั้นเป็นเรื่องที่ทำให้เลือดไหลเลอะ
MSalters

คุณหมายถึงคำตอบของฉันหรือแนวคิดของ OPs ในการจัดการคอลัมน์พิเศษทั้งหมดลงในตารางลูกค้าหรือไม่?
Andy

2
เป้าหมายที่นี่คือการหาวิธีการแก้ไขและบำรุงรักษาได้ การสร้างตารางต่อลูกค้าเป็นสิ่งที่ตรงกันข้าม ทุกครั้งที่คุณมีลูกค้าใหม่เข้ามามันไม่เหมือนจริง: รันสคริปต์สร้างตารางอัปเดตโค้ดของคุณ (ออบเจ็กต์เอนทิตี) และปรับใช้ใหม่
tsOverflow

ความคิดทั้งหมดของการใช้ตารางที่ใช้ร่วมกันสำหรับลูกค้าทั้งหมดนี้คือการอภิปรายสถาปัตยกรรม SaaS แยกต่างหากและมีเหตุผลที่ดีบางประการที่ทำให้ลูกค้าอยู่ในตารางที่แตกต่างกัน (หรือแม้กระทั่งในฐานข้อมูลที่แตกต่างกัน ในสถานการณ์สมมตินี้การสร้างคอลัมน์ cusotm ในตารางหลักนั้นไม่ใช่เรื่องง่าย ฉันโหวตขึ้นและฉันสงสัยว่าทำไมผู้คนถึงลงคะแนนเพียงเพราะพวกเขาไม่ชอบแนวทางนี้ เอฟเฟกต์แพลตฟอร์มด้านในนั้นเป็นจริง: โดยการใช้โมเดล EVA การสืบค้นของคุณจะยากขึ้นประหยัดมากขึ้นความสมบูรณ์ที่ยากขึ้น ฯลฯ
drizin

-1

วิธีแก้ปัญหาของฉันคิดว่าคุณจะโทรสอบถามนี้จากโปรแกรมและคุณควรจะสามารถดำเนินการโพสต์ คุณสามารถมีคอลัมน์ต่อไปนี้:

ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_VALUES

CUSTOM_VALUES จะเป็นประเภทสตริงที่จัดเก็บคีย์และค่าของคู่ สำคัญจะเป็นชื่อคอลัมน์และค่าจะเป็นค่าคอลัมน์เช่น

LIKE_MOVIE;yes;LIKE_MUSIC;no;FAV_CUISINE;rice

ใน CUSTOM_VALUES นี้คุณจะบันทึกเฉพาะข้อมูลที่มีอยู่ เมื่อคุณสอบถามจากโปรแกรมคุณสามารถแยกสตริงนี้และใช้งานได้

ฉันใช้ตรรกะนี้และมันใช้งานได้ดีเพียงแค่คุณจะต้องใช้ตรรกะการกรองในรหัสและไม่ได้อยู่ในแบบสอบถาม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.