ต้องการฐานข้อมูลการทำให้เป็นมาตรฐานกับความโปร่งใสของสคีมาหรือไม่


10

ความต้องการใหม่ได้ปรากฏขึ้นบน codebase เก่าซึ่งโดยทั่วไปจะช่วยให้การสื่อสารโดยตรง (ภายใน) ระหว่างสองคลาสก่อนหน้านี้ไม่เกี่ยวข้องโดยตรงของผู้ใช้ (เก็บไว้ในตารางที่แตกต่างกับสคีมาที่แตกต่างกันโดยสิ้นเชิงและเศร้ารหัสแทบไม่ทราบ ออกแบบน้อยดังนั้นจึงไม่มีชั้นผู้ปกครอง) เนื่องจากเราออกไปแขวนกระเป๋าในการตั้งค่าแบบเก่าที่ไม่เคยพิจารณาฟังก์ชั่นนี้มาก่อนจึงไม่มีการรับประกันว่าจะไม่มีการชนกันของ PK - เนื่องจากชุดข้อมูลที่ใช้อยู่นั้นรับประกันว่าจะมี

ดังนั้นวิธีการแก้ปัญหาที่เห็นได้ชัด: ฆ่ามันด้วยไฟและเขียนตารางการทำแผนที่ทั้งหมดของระเบียบ ฉันได้รับสองทิศทางสำหรับวิธีที่เป็นไปได้ในการนำแผนที่ไปใช้ แต่ฉันไม่ใช่ DBA ดังนั้นฉันจึงไม่แน่ใจว่ามีข้อดีหรือข้อเสียใดที่ฉันพลาดไป

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

การทำแผนที่ 1

(Professor_id, admin_id และ student_id เป็นรหัสต่างประเทศในตารางที่เกี่ยวข้อง)

| mailing_id (KEY) | professor_id | admin_id | student_id | 
-------------------------------------------------------
| 1001             |     NULL     |    87    |  NULL      |
| 1002             |     123      |   NULL   |  NULL      |
| 1003             |     NULL     |   NULL   |  123       |

+/- สำหรับวิธีนี้ดูเหมือนจะค่อนข้างหนักในข้อเสีย:

  • สองฟิลด์ที่ "สูญเปล่า" ต่อแถว
  • ละเมิด 2NF
  • ช่องโหว่ในการแทรก / อัปเดตความผิดปกติ (แถวที่มีชุดฟิลด์ 0-1 เท่านั้น NULL เช่น)

ข้อดีไม่ได้โดยไม่ต้องมีข้อดีของตัวเองแม้ว่า:

  • การแมปสามารถทำได้ด้วยการค้นหาเดียว
  • กำหนดข้อมูล "แหล่งที่มา" ได้อย่างง่ายดายสำหรับผู้ใช้ที่กำหนดจาก mailing_id

ในความจริงของฉันจะบอกฉันไม่ชอบความคิดนี้เลย

การทำแผนที่ 2

(สมมติว่า MSG_ * เป็นค่าคงที่ประเภท enum หรือตัวระบุอื่นที่เหมาะสม)

| mailing_id (KEY)  | user_type (UNIQUE1) | internal_id (UNIQUE2)| 
------------------------------------------------------------------
| 1001              | MSG_ADMIN          | 87                    |
| 1002              | MSG_PROF           | 123                   |
| 1003              | MSG_STUDENT        | 123                   |

ด้วยการตั้งค่านี้และดัชนีคอมโพสิตที่เป็นเอกลักษณ์ของ {user_type, internal_id} ทุกอย่างกลายเป็นสิ่งที่สะอาดกว่าเดิม 3NF ได้รับการดูแลรักษาและรหัสแอปพลิเคชันไม่จำเป็นต้องตรวจสอบความผิดปกติของ I / U

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

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


2
คุณอาจพบความคิดของ Martin Fowler ในบทบาทที่น่าสนใจอ่าน
Marjan Venema

มันน่าสนใจจริงๆ น่าเศร้าที่ไม่เข้าใจถึงปัญหาเฉพาะของฉันมากเกินไป
GeminiDomino

คุณจะได้รับอาจารย์ที่เป็นผู้บริหารและนักเรียนที่ได้งานในการบริหารหรือแม้กระทั่งกลับมา 10 ปีต่อมาในฐานะอาจารย์ คุณอาจมีพวกเขาอยู่แล้ว คุณจะแยกพวกนั้นออกจากกันหรือพยายามรวมกัน?
Elin

บทบาทเป็นเพียงตัวอย่าง แต่ฉันเห็นประเด็นของคุณ ในทางปฏิบัติแม้ว่าผู้ใช้เปลี่ยนบทบาทพวกเขาจะยังคงเป็นบันทึกแยกต่างหากอยู่ดี
GeminiDomino

ถ้าจะดีถ้าคุณวลีอีกวรรคหนึ่ง มันค่อนข้างชัดเจน ฉันหมายถึงมันชัดเจนว่ามีปัญหา แต่ไม่ชัดเจนว่ามันคืออะไร
Tulains Córdova

คำตอบ:


1

แนวคิดที่สองของคุณคือแนวคิดที่ถูกต้อง วิธีนี้ช่วยให้คุณทำแผนที่ทั้งหมดที่คุณต้องทำเพื่อรวมช่องว่างที่สำคัญสามการชนกันของคุณ

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

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

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

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


3

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

มันไม่ค่อยสวย แต่ก็มีข้อดีอยู่เล็กน้อย ...

  1. การจับคู่โครงสร้างที่มีอยู่จะง่ายขึ้นสำหรับคนอื่น ๆ ที่จะทำงานกับสคีนี้ก่อนที่จะนำไปทุ่งหญ้า
  2. คุณไม่มีฟิลด์ที่สูญเปล่าและคุณไม่ได้ขอให้ db จับคู่สิ่งที่ไม่มีอยู่
  3. เพราะแต่ละตารางจะมีเพียงกันและมันจะค่อนข้างง่ายในการสร้างมุมมองที่เชื่อมโยงข้อมูลทั้งหมดสำหรับกิจวัตรของคุณที่จะใช้

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


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

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

ฟิลด์ "ประเภทผู้ใช้" จะเป็นตัวกำหนดตารางที่จะเชื่อมโยงกับบันทึกเฉพาะนั้น มันจะต้องได้รับการจัดการในระดับแอปพลิเคชันอย่างใดอย่างหนึ่งและเนื่องจากพวกเขาอยู่ในตารางที่แตกต่างกันจึงไม่มีวิธีที่ดีที่จะทำให้มันเป็นข้อ จำกัด ที่สำคัญต่างประเทศ นักพัฒนาดั้งเดิมดูเหมือนจะไม่ได้พิจารณาปัญหานี้เลยโชคไม่ดีซึ่งเป็นสาเหตุที่ทำให้เกิดความยุ่งเหยิง :)
GeminiDomino
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.