วิธีที่เหมาะสมในการจัดเก็บค่าที่อาจแตกต่างกันหลายประเภท


11

ฉันมีตารางคำตอบและตารางคำถาม

ตารางคำตอบมีค่า แต่ขึ้นอยู่กับคำถามที่ว่าค่านี้อาจจะเป็นbit, nvarcharหรือnumber(ไกล) คำถามที่มีความคิดของสิ่งที่คำตอบประเภทค่าตั้งใจที่ควรจะเป็น

การแยกวิเคราะห์ค่าคำตอบเหล่านี้จะต้องมีความสำคัญเนื่องจากจะต้องเปรียบเทียบอย่างน้อยหนึ่งตัวเลข

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

ตัวเลือกสองสามอย่างที่ฉันพิจารณาคือ:

A. XML หรือสตริงที่ได้รับการวิเคราะห์คำแตกต่างกันไปขึ้นอยู่กับประเภทที่ต้องการ (ซึ่งถูกติดตามในคำถาม)

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

C. สามคอลัมน์แยกกันในตาราง Answer ที่สามารถดึงข้อมูลได้ตามประเภทที่ต้องการ

ฉันยินดีที่จะได้รับข้อมูลเกี่ยวกับข้อดีข้อเสียของวิธีการเหล่านี้หรือวิธีการอื่นที่ฉันไม่ได้พิจารณา

คำตอบ:


2

มันขึ้นอยู่กับว่าส่วนหน้าของคุณเข้าถึงข้อมูลอย่างไร

ถ้าคุณใช้ O / R-mapper ให้เน้นการออกแบบเชิงวัตถุของคลาสของคุณไม่ใช่ที่การออกแบบฐานข้อมูล ฐานข้อมูลนั้นเพียงแค่สะท้อนการออกแบบชั้นเรียน การออกแบบ db ที่แน่นอนนั้นขึ้นอยู่กับโมเดลการแมป O / R-mapper และการสืบทอดที่คุณใช้

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

หรือคุณสามารถใช้หนึ่งคอลัมน์ต่อประเภทค่า เรามีเทราไบต์ในวันนี้!

คอลัมน์ XML เป็นไปได้ แต่อาจเพิ่มความซับซ้อนมากขึ้นเมื่อเทียบกับคอลัมน์ข้อความแบบง่ายและทำได้ในสิ่งเดียวกันนั่นก็คือ serializing / deserializing

ตารางรวมที่แยกเป็นวิธีที่ถูกต้องในการทำสิ่งต่าง ๆ แต่ก็เพิ่มความซับซ้อนได้เช่นกัน

ง่าย ๆ เข้าไว้.

ดูคำตอบของฉันในการออกแบบฐานข้อมูลแบบสอบถาม - วิธีไหนดีกว่ากัน? .


4

จากสิ่งที่คุณพูดฉันจะใช้สคีมาทั่วไปดังต่อไปนี้:

CREATE TABLE [dbo].[PollQuestion]
(
    [PollQuestionId] INT NOT NULL PRIMARY KEY IDENTITY,
    [QuestionText] NVARCHAR(150) NOT NULL, -- Some reasonable character limit
    [Created] DATETIME2(2) NOT NULL DEFAULT SYSUTCDATETIME(),
    [Archived] DATETIME2(2) NULL,  -- Remove this if you don't need to hide questions
)
CREATE TABLE [dbo].[PollOption]
(
    [PollOptionId] INT NOT NULL PRIMARY KEY IDENTITY,
    [PollQuestionId] INT NOT NULL,  -- Link to the question here because options aren't shared across questions
    [OptionText] NVARCHAR(50) NOT NULL, -- Some reasonable character limit
    [Created] DATETIME2(2) NOT NULL DEFAULT SYSUTCDATETIME(),
    [Archived] DATETIME2(2) NULL  -- Remove this if you don't need to hide options

    CONSTRAINT [FK_PollOption_PollQuestionId_to_PollQuestion_PollQuestionId] FOREIGN KEY ([PollQuestionId]) REFERENCES [dbo].[PollQuestion]([PollQuestionId])
)
CREATE TABLE [dbo].[PollResponse]
(
    [PollResponseId] INT NOT NULL PRIMARY KEY IDENTITY,
    [PollOptionId] INT NOT NULL,
    [UserId] INT NOT NULL,
    [Created] DATETIME2(2) NOT NULL DEFAULT SYSUTCDATETIME(),
    [Archived] DATETIME2(2) NULL,  -- Remove this if you don't need to hide answers

    CONSTRAINT [FK_PollResponse_PollOptionId_to_PollOption_PollOptionId] FOREIGN KEY ([PollOptionId]) REFERENCES [dbo].[PollOption]([PollOptionId]),
    CONSTRAINT [FK_PollResponse_UserId_to_User_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User]([UserId])
)

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

คำถามและคำตอบที่อาจเกิดขึ้นจะถูกรวบรวมจากผู้ใช้คนแรกและแทรกลงในตาราง PollQuestion และ PollOption ผู้ใช้รายที่สองที่ตอบคำถามจะเลือกจากรายการคำตอบ (จริง / เท็จ = รายการ 2) คุณสามารถขยายตาราง PollQuestion เพื่อรวมรหัสผู้ใช้ของผู้สร้างได้หากเหมาะสมเพื่อติดตามคำถามที่พวกเขาสร้าง

บน UI ของคุณคำตอบที่ผู้ใช้เลือกสามารถเชื่อมโยงกับค่า PollOptionId ร่วมกับ PollQuestionId คุณสามารถตรวจสอบว่าคำตอบนั้นถูกต้องสำหรับคำถามอย่างรวดเร็ว การตอบสนองของพวกเขาหากถูกต้องจะถูกป้อนในตาราง PollResponse

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

CREATE TABLE [dbo].[PollResponse]
(
    [PollResponseId] INT NOT NULL PRIMARY KEY IDENTITY,
    [PollOptionId] INT NULL,
    [PollQuestionId] INT NOT NULL,
    [UserId] INT NOT NULL,
    [AlternateResponse] NVARCHAR(50) NULL, -- Some reasonable character limit
    [Created] DATETIME2(2) NOT NULL DEFAULT SYSUTCDATETIME(),
    [Archived] DATETIME2(2) NULL,  -- Remove this if you don't need to hide answers

    CONSTRAINT [FK_PollResponse_PollOptionId_to_PollOption_PollOptionId] FOREIGN KEY ([PollOptionId]) REFERENCES [dbo].[PollOption]([PollOptionId]),
    CONSTRAINT [FK_PollResponse_UserId_to_User_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User]([UserId])
)

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

แก้ไข: การสื่อสารประเภทข้อมูลสำหรับ AlternateResponse

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

CREATE TABLE [dbo].[PollQuestion]
(
    [PollQuestionId] INT NOT NULL PRIMARY KEY IDENTITY,
    [QuestionText] NVARCHAR(150) NOT NULL, -- Some reasonable character limit
    [QuestionDataTypeId] INT NOT NULL,
    [Created] DATETIME2(2) NOT NULL DEFAULT SYSUTCDATETIME(),
    [Archived] DATETIME2(2) NULL,  -- Remove this if you don't need to hide questions
    -- Insert FK here for QuestionDataTypeId
)
CREATE TABLE [dbo].[QuestionDataType]
(
    [QuestionDataTypeId] INT NOT NULL PRIMARY KEY IDENTITY,
    [Description] NVARCHAR(50) NOT NULL, -- Some reasonable character limit
)

คุณสามารถแสดงประเภทข้อมูลที่มีอยู่ทั้งหมดสำหรับผู้สร้างคำถามโดยเลือกจากตาราง QuestionDataType นี้ UI ของคุณสามารถอ้างอิง QuestionDataTypeId เพื่อเลือกรูปแบบที่เหมาะสมสำหรับฟิลด์ตอบกลับสำรอง คุณไม่ได้ จำกัด ประเภทข้อมูล TSQL ดังนั้น "หมายเลขโทรศัพท์" จึงอาจเป็นประเภทข้อมูลและคุณจะได้รับการจัดรูปแบบ / ปิดบังบน UI ที่เหมาะสม นอกจากนี้หากต้องการคุณสามารถส่งข้อมูลของคุณไปยังประเภทที่เหมาะสมผ่านคำสั่งกรณีง่ายเพื่อทำการประมวลผลทุกชนิด (เลือก, การตรวจสอบ, ฯลฯ ) ในคำตอบอื่น


0

ดูที่EAV นั้นเลวร้ายขนาดไหน? โดย Aaron Bertrand สำหรับข้อมูลบางอย่างเกี่ยวกับรุ่น EAV

น่าจะดีกว่าในหลายวิธีที่จะมีคอลัมน์สำหรับแต่ละประเภทข้อมูลแทนที่จะมี XML หรือหลายตาราง

ส่วนที่ จำกัด นั้นง่าย:

CHECK 
(
    CASE WHEN col1 IS NOT NULL THEN 1 ELSE 0 END + 
    CASE WHEN col2 IS NOT NULL THEN 1 ELSE 0 END + 
    CASE WHEN col3 IS NOT NULL THEN 1 ELSE 0 END = 1
)

มีคำถามและคำตอบที่มีอยู่มากมายในไซต์นี้ที่ติดแท็ก และอาจเป็นไปได้ว่าคนอื่น ๆ ที่ผู้ถามไม่รู้จักที่จะใช้คำนั้นในคำถามของพวกเขา

ฉันขอแนะนำให้อ่านสิ่งเหล่านี้เนื่องจากพวกเขาจะครอบคลุมข้อดีและข้อเสียทั้งหมด (สิ่งนี้จะป้องกันไม่ให้ผู้คนมาขัดจังหวะพวกเขาใหม่ที่นี่เมื่อในความเป็นจริงพวกเขาไม่ได้เปลี่ยน)

คำตอบตามความเห็นของคำถามที่Aaron Bertrand ออกให้


-1

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

ฉันจะไปกับ NVARCHAR (MAX) แล้วปล่อยให้ส่วนหน้าจัดการกับการจัดเก็บ / ดึงเนื้อหา อาจเป็นฟิลด์บิต IS_CORRECT ที่ส่วนหน้าสามารถจัดเก็บได้หากคำตอบนั้นถูกต้อง

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