การใช้ตารางการค้นหาอย่างเหมาะสม


25

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

สมมติว่าฉันมีตารางชื่อพนักงาน:

ID  LName   FName   Gender  Position
1   Doe     John    Male    Manager
2   Doe     Jane    Female  Sales
3   Smith   John    Male    Sales

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

ID  Position
1   Manager
2   Sales

แต่ฉันจะแยกข้อมูลออกเป็นตารางการค้นหาขนาดเล็กลงต่อไปได้อีกนานเท่าใดจึงจะไม่สามารถจัดการได้ ฉันสามารถสร้างตารางเพศและมี 1 สอดคล้องกับเพศชายและ 2 สอดคล้องกับเพศหญิงในตารางการค้นหาแยกต่างหาก ฉันสามารถใส่ LNames และ FNames ลงในตารางได้ รายการ "John" ทั้งหมดจะถูกแทนที่ด้วย foreign key 1 ที่ชี้ไปที่ตาราง FName ที่ระบุว่า ID 1 สอดคล้องกับ John หากคุณลงไปในช่องกระต่ายนี้มากเกินไปเช่นนี้ตารางพนักงานของคุณจะถูกลดขนาดไปเป็นระเบียบต่างประเทศ:

ID  LName   FName   Gender  Position
1   1       1       1       1
2   1       2       2       2
3   2       1       1       2

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


5
การใช้ตาราง "ค้นหา" เป็นสิ่งหนึ่ง การแทนที่ข้อความด้วยหมายเลขรหัสเป็นสิ่งที่แตกต่างอย่างสิ้นเชิง
ไมค์ Sherrill 'Cat Recall'

1
เพศอาจไม่ได้รับการแก้ไขเป็น 2 ค่าเสมอไป! ตอนนี้เรามีการเปลี่ยนเพศใครจะบอกว่าแอปพลิเคชันอาจไม่ต้องการหมวดหมู่เพิ่มเติมเช่น 'ชายที่เกิดตอนนี้ผู้หญิง' หรือ 'ผู้หญิงที่เกิดตอนนี้เพศชาย'

@ ไมค์ความคิดเห็นดี!
วอลเตอร์ Mitty

ในร้านของฉันนักคิดสามารถหยุดได้หลังจากทางเลือกสี่ทางเท่านั้นเพศชายเพศหญิงจะไม่เปิดเผย
kevinsky

คำตอบ:


22

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

คุณกำลังผสมสองประเด็นที่แตกต่างกัน ปัญหาหนึ่งคือการใช้ตาราง "ค้นหา"; อื่น ๆ คือการใช้กุญแจตัวแทน (หมายเลขรหัส)

เริ่มด้วยตารางนี้

ID  LName   FName   Gender  Position
1   Doe     John    Male    Manager
2   Doe     Jane    Female  Sales
3   Smith   John    Male    Sales

คุณสามารถสร้างตาราง "ค้นหา" สำหรับตำแหน่งเช่นนี้

create table positions (
  pos_name varchar(10) primary key
);

insert into positions
select distinct position 
from employees;

alter table employees
add constraint emp_fk1
foreign key (position) 
  references positions (pos_name);

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

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

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


2
ฉันไม่รู้ว่าคุณทำได้ทั้งหมด! วิธีการทำงานของคุณนั้นสวยงามมาก ขอขอบคุณ!
Brad Turner

4
ฉันเข้าร่วม DBA Stack Exchange เพียงเพื่อให้ฉันสามารถโหวตคำตอบนี้ได้ มันสวยงามและไม่เคยเกิดขึ้นกับฉัน ขอบคุณ!
CindyH

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

8

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

  • เพศเป็นการอธิบายตนเอง (พูดMหรือF) จำกัด 2 ค่าและสามารถบังคับใช้กับข้อ จำกัด การตรวจสอบ คุณจะไม่เพิ่มเพศใหม่ (ไม่สนใจการแก้ไขความถูกต้องทางการเมือง)
  • ชื่อแรก "จอห์น" ไม่ได้เป็นส่วนหนึ่งของชุดข้อมูลที่ จำกัด และถูก จำกัด : ชุดข้อมูลที่มีศักยภาพมีขนาดใหญ่จนถึงจุดที่ไร้ขีด จำกัด อย่างมีประสิทธิภาพดังนั้นจึงไม่ควรเป็นการค้นหา

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

นอกจากนี้เมื่อคุณมีพนักงานนับล้านคนแล้วมันจะมีประสิทธิภาพมากขึ้นในการจัดเก็บขนาดเล็ก PositionID กว่า varchar

มาเพิ่มคอลัมน์ "สกุลเงินเงินเดือน" ใหม่กันเถอะ ฉันจะใช้ตารางการค้นหาที่นี่พร้อมกับกุญแจของ CHF, GBP, EUR, USD และอื่น ๆ : ฉันจะไม่ใช้กุญแจตัวแทน สิ่งนี้อาจถูก จำกัด ด้วยข้อ จำกัด การตรวจสอบเช่นออฟ แต่มันเป็นชุดข้อมูลที่ จำกัด แต่ขยายได้เช่นตำแหน่ง ฉันยกตัวอย่างนี้เพราะฉันใช้คีย์ธรรมชาติแม้ว่าจะปรากฏในข้อมูลแถวพนักงานนับล้านแถวแม้จะเป็นถ่าน (3) แทนที่จะเป็นแท่งเล็ก ๆ

ดังนั้นเพื่อสรุปคุณใช้ตารางการค้นหา

  1. ที่ซึ่งคุณมีข้อมูล จำกัด แต่ยังขยายได้ในคอลัมน์
  2. ที่ไม่ได้อธิบายตัวเองอยู่ที่ไหน
  3. เพื่อหลีกเลี่ยงความผิดปกติในการปรับเปลี่ยนข้อมูล

1
เหตุผลหนึ่งที่เป็นไปได้ที่จะใส่เพศลงในตารางการค้นหาคือการแปล
a_horse_with_no_name

1
"เพศ ... (พูดว่า M หรือ F) จำกัด เพียง 2 ค่า ... ไม่สนใจความถูกต้องทางการเมือง" - น่าขันก็คือความถูกต้องทางการเมืองแบบเดียวกับที่คุณดูเหมือนจะเกลียดชังที่ทำให้คน "เพศ" ไม่ถูกต้อง (' ผู้ชาย ',' ผู้หญิง ') เมื่อพวกเขาหมายถึง "เพศ" ("ชาย", "หญิง") หากบริบทเป็นเพศไวยกรณ์แล้วมักจะมีค่ามากกว่าสองค่า หากบริบทกำลังบันทึกเพศของทารกแรกเกิดจะมีค่าอย่างน้อยสี่ค่า ('ยังไม่ได้รับการประเมินอย่างเป็นทางการ' และ 'การประเมินอย่างเป็นทางการไม่สามารถสรุปได้') PS ผมไม่ได้หมายถึงเสียงที่รุนแรงผมมีความสุขประชด :)
onedaywhen

4
@onedaywhen: ค่าที่ถูกต้องสำหรับคอลัมน์ที่ชื่อว่า "เพศ" คือ "ใช่โปรด" ถ้าคุณกำลังอังกฤษ
GBN

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

5

คำตอบคือ "มันขึ้นอยู่กับ" ไม่ค่อยพอใจเท่าไหร่นัก แต่มีอิทธิพลมากมายในการผลักและดึงการออกแบบ หากคุณมีโปรแกรมเมอร์แอปออกแบบโครงสร้างฐานข้อมูลเหมือนที่คุณอธิบายทำงานให้กับพวกเขาเพราะ ORM ซ่อนความซับซ้อน คุณจะดึงผมออกเมื่อคุณเขียนรายงานและต้องเข้าร่วมสิบโต๊ะเพื่อรับที่อยู่

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

ในการใช้คำพูดที่ชื่นชอบซ้ำ

"นักปราชญ์ครั้งหนึ่งเคยบอกฉันว่า" ทำให้เป็นปกติจนกว่ามันจะเจ็บปวด

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

ใช้ตัวอย่างย่อของตารางที่มีการทำให้เป็นมาตรฐานสูงจากระบบจริง

CREATE TABLE PROPERTY
(ID                          NUMBER(9)           NOT NULL);

CREATE TABLE PROPERTY_TYPE
(ID                          NUMBER(9)           NOT NULL);

CREATE TABLE PROPERTY_LOCALE 
PROPERTY_ID                  NUMBER(9)           NOT NULL,
(LOCALE_ID                   NUMBER(9)           NOT NULL,  --language 
VALUE                        VARCHAR2(200)       NOT NULL);

CREATE TABLE PROPERTY_DEPENDENCY
(PROPERTY_ID                 NUMBER(9)           NOT NULL,
 PARENT_PROPERTY_ID          NUMBER(9)                   ,
 PROPERTY_TYPE_ID            NUMBER(9)           NOT NULL);

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

  CREATE TABLE CASE_PROPERTY
  (ID                        NUMBER(9)           NOT NULL,
  PARENT_ID                  NUMBER(9),
  CASE_ID                    NUMBER(9)           NOT NULL,
  PROPERTY_ID                NUMBER(9),
  PROPERTY_TYPE_ID           NUMBER(9)           NOT NULL);

สิ่งนี้ดูดี: รับทุกกรณีด้วย property_id ในตัวเลือกเดียว

มารับรายการกันเลย

 Select pl.value, pd.property_id
 from property_locale pl, property_dependency pd
 where pl.property_id = pd.property_id
 and pd.property_type_id = 2;  --example number

ทีนี้ลองเลือกคุณสมบัติทั้งหมดของเคสถ้ามันมี property_types เป็น 3 และ 4 และ 5 หรือไม่ ...

SELECT   cp2.case_id,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 2
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE1,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 34
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE2,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 4
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE3
  FROM   case_property cp2
 WHERE   cp2.case_id = 10293  

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

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


5
หมายเลข ID ไม่มีส่วนเกี่ยวข้องกับการทำให้เป็นมาตรฐาน เพียงเพราะทุกตารางมีหมายเลขรหัสไม่ได้หมายความว่ามันอยู่ใน 5NF หรือแม้แต่ใน 3NF หมายความว่าคุณต้องเข้าร่วมจำนวนมากเพื่อรับข้อมูลที่ใช้งานได้จากตารางนั้น
Mike Sherrill 'Cat Recall'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.