การวิเคราะห์สถานการณ์ - ซึ่งนำเสนอลักษณะที่เกี่ยวข้องกับเรื่องที่เรียกว่าฐานข้อมูลชั่วคราว - จากมุมมองแนวคิดหนึ่งสามารถกำหนดได้ว่า: (a) " เรื่องราว " ปัจจุบัน " เรื่องราวของบล็อกและ (b)" เรื่องราวในอดีต " บล็อกเรื่องแม้ว่า คล้ายกันเป็นหน่วยงานประเภทต่าง ๆ
นอกจากนั้นเมื่อทำงานในระดับตรรกะของสิ่งที่เป็นนามธรรมข้อเท็จจริง (แสดงโดยแถว) ของชนิดที่แตกต่างจะต้องถูกเก็บไว้ในตารางที่แตกต่างกัน ในกรณีที่อยู่ระหว่างการพิจารณาแม้ในขณะที่คล้ายกันมาก (i) ข้อเท็จจริงเกี่ยวกับ“ปัจจุบัน” รุ่นจะแตกต่างจาก (ii) ข้อเท็จจริงเกี่ยวกับ“ที่ผ่านมา” รุ่น
ดังนั้นฉันขอแนะนำให้จัดการสถานการณ์โดยใช้สองตาราง:
แต่ละคอลัมน์มี (1) คอลัมน์ที่แตกต่างกันเล็กน้อยและ (2) กลุ่มของข้อ จำกัด ที่แตกต่างกัน
กลับไปที่ชั้นความคิดผมคิดว่า -in ธุรกิจ environment- ของผู้เขียนและบรรณาธิการที่มีความคิดที่สามารถเบี่ยงเป็นบทบาทที่สามารถเล่นได้โดยผู้ใช้และสิ่งเหล่านี้ที่สำคัญขึ้นอยู่กับข้อมูลที่มา (ผ่านการดำเนินงานการจัดการลอจิคัลระดับ) และการตีความ (ดำเนินการโดยผู้อ่านและผู้เขียนบล็อกเรื่องราวในระดับภายนอกของระบบข้อมูลคอมพิวเตอร์ด้วยความช่วยเหลือของโปรแกรมแอปพลิเคชันหนึ่งโปรแกรมหรือมากกว่า)
ฉันจะให้รายละเอียดเกี่ยวกับปัจจัยเหล่านี้และประเด็นที่เกี่ยวข้องอื่น ๆ ดังนี้
กฎเกณฑ์ทางธุรกิจ
ตามความเข้าใจของฉันเกี่ยวกับความต้องการของคุณสูตรทางธุรกิจต่อไปนี้ (รวมกันในแง่ของประเภทนิติบุคคลที่เกี่ยวข้องและประเภทของความสัมพันธ์) มีประโยชน์เป็นพิเศษในการสร้างสคีแนวคิดที่สอดคล้องกัน:
- ผู้ใช้เขียนเป็นศูนย์หนึ่งหรือหลายBlogStories
- BlogStoryถือเป็นศูนย์หนึ่งหรือหลายBlogStoryVersions
- ผู้ใช้เขียนเป็นศูนย์หนึ่งหรือหลายBlogStoryVersions
ไดอะแกรม IDEF1X ของที่เก็บข้อมูล
ดังนั้นเพื่อที่จะอธิบายคำแนะนำของฉันโดยอาศัยอำนาจของอุปกรณ์กราฟิกฉันได้สร้างตัวอย่าง IDEF1X แผนภาพที่ได้รับมาจากกฎเกณฑ์ทางธุรกิจสูตรข้างต้นและคุณสมบัติอื่น ๆ ที่ดูเหมือนเกี่ยวข้อง มันแสดงในรูปที่ 1 :
เหตุใดBlogStoryและBlogStoryVersion จึงกำหนดแนวคิดเป็นเอนทิตีที่แตกต่างกันสองประเภท
เพราะ:
BlogStoryVersionอินสแตนซ์ (เช่น“ที่ผ่านมา” อย่างใดอย่างหนึ่ง) เสมอถือเป็นค่าสำหรับUpdatedDateTimeคุณสมบัติในขณะที่BlogStoryเกิดขึ้น (เช่น“ปัจจุบัน” หนึ่ง) ไม่เคยถือมัน
นอกจากนี้เอนทิตีของประเภทเหล่านั้นจะถูกระบุด้วยค่าของคุณสมบัติสองชุดที่แตกต่างกัน: BlogStoryNumber (ในกรณีของการเกิดBlogStory ) และBlogStoryNumberบวกCreatedDateTime (ในกรณีของอินสแตนซ์BlogStoryVersion )
นิยามบูรณาการสำหรับแบบจำลองข้อมูล ( IDEF1X ) เป็นข้อมูลที่ควรเผื่อการสร้างแบบจำลองเทคนิคที่ได้รับการยอมรับว่าเป็นมาตรฐานในเดือนธันวาคมปี 1993 โดยสหรัฐอเมริกาสถาบันมาตรฐานและเทคโนโลยี (NIST) มันขึ้นอยู่กับเนื้อหาทางทฤษฎีในช่วงต้นที่เขียนโดยผู้สร้าง แต่เพียงผู้เดียวของรูปแบบเชิงสัมพันธ์คือดร. EF Codd ; ในมุมมอง Entity-Relationshipของข้อมูลที่พัฒนาโดย Dr. PP Chen ; และยังเกี่ยวกับเทคนิคการออกแบบฐานข้อมูลแบบลอจิคัลสร้างโดย Robert G. Brown
โครงร่าง SQL-DDL เชิงตรรกะ
จากนั้นจากการวิเคราะห์แนวคิดที่นำเสนอก่อนหน้านี้ฉันได้ประกาศการออกแบบระดับตรรกะด้านล่าง:
-- You should determine which are the most fitting
-- data types and sizes for all your table columns
-- depending on your business context characteristics.
-- Also you should make accurate tests to define the most
-- convenient index strategies at the physical level.
-- As one would expect, you are free to make use of
-- your preferred (or required) naming conventions.
CREATE TABLE UserProfile (
UserId INT NOT NULL,
FirstName CHAR(30) NOT NULL,
LastName CHAR(30) NOT NULL,
BirthDate DATETIME NOT NULL,
GenderCode CHAR(3) NOT NULL,
UserName CHAR(20) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT UserProfile_PK PRIMARY KEY (UserId),
CONSTRAINT UserProfile_AK1 UNIQUE ( -- Composite ALTERNATE KEY.
FirstName,
LastName,
BirthDate,
GenderCode
),
CONSTRAINT UserProfile_AK2 UNIQUE (UserName) -- ALTERNATE KEY.
);
CREATE TABLE BlogStory (
BlogStoryNumber INT NOT NULL,
Title CHAR(60) NOT NULL,
Content TEXT NOT NULL,
CoverImageName CHAR(30) NOT NULL,
IsActive BIT(1) NOT NULL,
AuthorId INT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT BlogStory_PK PRIMARY KEY (BlogStoryNumber),
CONSTRAINT BlogStory_AK UNIQUE (Title), -- ALTERNATE KEY.
CONSTRAINT BlogStoryToUserProfile_FK FOREIGN KEY (AuthorId)
REFERENCES UserProfile (UserId)
);
CREATE TABLE BlogStoryVersion (
BlogStoryNumber INT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
Title CHAR(60) NOT NULL,
Content TEXT NOT NULL,
CoverImageName CHAR(30) NOT NULL,
IsActive BIT(1) NOT NULL,
AuthorId INT NOT NULL,
UpdatedDateTime DATETIME NOT NULL,
--
CONSTRAINT BlogStoryVersion_PK PRIMARY KEY (BlogStoryNumber, CreatedDateTime), -- Composite PK.
CONSTRAINT BlogStoryVersionToBlogStory_FK FOREIGN KEY (BlogStoryNumber)
REFERENCES BlogStory (BlogStoryNumber),
CONSTRAINT BlogStoryVersionToUserProfile_FK FOREIGN KEY (AuthorId)
REFERENCES UserProfile (UserId),
CONSTRAINT DatesSuccession_CK CHECK (UpdatedDateTime > CreatedDateTime) --Let us hope that MySQL will finally enforce CHECK constraints in a near future version.
);
ทดสอบในซอฟท์แวร์ SQL นี้ที่ทำงานบน MySQL 5.6
BlogStory
ตาราง
อย่างที่คุณเห็นในการออกแบบการสาธิตฉันได้กำหนดBlogStory
คอลัมน์หลัก (PK สำหรับความกะทัดรัด) ด้วยประเภทข้อมูล INT ในเรื่องนี้คุณอาจต้องการแก้ไขกระบวนการอัตโนมัติในตัวที่สร้างและกำหนดค่าตัวเลขสำหรับคอลัมน์ดังกล่าวในทุกการแทรกแถว หากคุณไม่ต้องการเว้นช่องว่างเป็นครั้งคราวในชุดค่านี้คุณสามารถใช้แอตทริบิวต์AUTO_INCREMENTซึ่งมักใช้ในสภาพแวดล้อม MySQL
เมื่อป้อนBlogStory.CreatedDateTime
จุดข้อมูลส่วนบุคคลทั้งหมดของคุณคุณสามารถใช้ฟังก์ชัน NOW ()ซึ่งจะส่งกลับค่าวันที่และเวลาที่เป็นปัจจุบันในเซิร์ฟเวอร์ฐานข้อมูลที่การดำเนินการ INSERT ที่แน่นอนทันที สำหรับฉันแล้วการฝึกฝนนี้เหมาะสมกว่าและมีแนวโน้มที่จะเกิดข้อผิดพลาดน้อยกว่าการใช้งานประจำภายนอก
โดยมีเงื่อนไขว่าตามที่กล่าวไว้ในความคิดเห็น (ลบออกแล้ว) คุณต้องการหลีกเลี่ยงความเป็นไปได้ในการรักษาBlogStory.Title
ค่าที่ซ้ำกันคุณจะต้องตั้งค่าข้อ จำกัดUNIQUEสำหรับคอลัมน์นี้ เนื่องจากความจริงที่ได้รับชื่อเรื่องอาจจะใช้ร่วมกันโดยหลายคน (หรือแม้กระทั่งทั้งหมดของ)“ที่ผ่านมา” BlogStoryVersionsแล้วข้อ จำกัด UNIQUE ควรได้รับการจัดตั้งขึ้นสำหรับBlogStoryVersion.Title
คอลัมน์
ฉันรวมBlogStory.IsActive
คอลัมน์ประเภทBIT (1) (แม้ว่าอาจใช้TINYINT ได้เช่นกัน) ในกรณีที่คุณต้องการฟังก์ชั่นลบ "อ่อน" หรือ "ตรรกะ"
รายละเอียดเกี่ยวกับBlogStoryVersion
ตาราง
ในทางกลับกันค่า PK ของ BlogStoryVersion
ตารางประกอบด้วย (a) BlogStoryNumber
และ (b) คอลัมน์ที่ชื่อว่าCreatedDateTime
แน่นอนทำเครื่องหมายทันทีที่แม่นยำซึ่งBlogStory
แถวนั้นได้รับการแทรก
BlogStoryVersion.BlogStoryNumber
นอกเหนือจากการเป็นส่วนหนึ่งของการ PK ก็ยัง จำกัด เป็นคีย์ต่างประเทศ (FK) ที่อ้างอิงBlogStory.BlogStoryNumber
, การกำหนดค่าที่บังคับ Referential Integrityระหว่างแถวของตารางทั้งสองนี้ ในแง่นี้การใช้การสร้างอัตโนมัติของ a BlogStoryVersion.BlogStoryNumber
ไม่จำเป็นเนื่องจากการตั้งค่าเป็น FK ค่าที่แทรกลงในคอลัมน์นี้จะต้อง "ดึงออกมาจาก" ค่าที่อยู่ในBlogStory.BlogStoryNumber
คู่ที่เกี่ยวข้องแล้ว
BlogStoryVersion.UpdatedDateTime
คอลัมน์ควรเก็บรักษาเป็นไปตามคาดจุดในเวลาเมื่อBlogStory
แถวมีการปรับเปลี่ยนและเป็นผลให้เพิ่มเข้าไปในBlogStoryVersion
ตาราง ดังนั้นคุณสามารถใช้ฟังก์ชัน NOW () ในสถานการณ์นี้ได้เช่นกัน
ช่วงเข้าใจระหว่างBlogStoryVersion.CreatedDateTime
และBlogStoryVersion.UpdatedDateTime
เป็นการแสดงออกทั้งหมดระยะเวลาในระหว่างที่BlogStory
แถวคือ“ปัจจุบัน” หรือ“ปัจจุบัน”
ข้อควรพิจารณาสำหรับ Version
คอลัมน์
มันจะมีประโยชน์ที่จะคิดว่าBlogStoryVersion.CreatedDateTime
เป็นคอลัมน์ที่เก็บค่าที่แสดงให้เห็นโดยเฉพาะอย่างยิ่ง“ที่ผ่านมา” เวอร์ชันของBlogStory ฉันเห็นว่าสิ่งนี้มีประโยชน์มากกว่าVersionId
หรือVersionCode
เพราะผู้ใช้เป็นมิตรในแง่ที่ว่าผู้คนมักจะคุ้นเคยกับแนวคิดเรื่องเวลา ตัวอย่างเช่นผู้เขียนบล็อกหรือผู้อ่านสามารถอ้างถึงBlogStoryVersionในรูปแบบที่คล้ายกับต่อไปนี้:
- “ผมต้องการที่จะเห็นเฉพาะเวอร์ชันของBlogStoryระบุจำนวน
1750
ที่ถูกสร้างบน26 August 2015
เวลา9:30
”
ผู้เขียนและบรรณาธิการบทบาท: ที่มาของข้อมูลและการตีความ
ด้วยวิธีนี้คุณสามารถแยกแยะความแตกต่างที่ถือ“ต้นฉบับ” AuthorId
ของคอนกรีตBlogStoryเลือก“ที่เก่าแก่ที่สุด” เวอร์ชันของบางอย่างBlogStoryId
จากBlogStoryVersion
ตารางโดยอาศัยอำนาจของการใช้MIN () ฟังก์ชั่นBlogStoryVersion.CreatedDateTime
การ
ด้วยวิธีนี้แต่ละBlogStoryVersion.AuthorId
คุ้มค่าที่มีอยู่ในทุกส่วน“ต่อมา” หรือ“ประสบความสำเร็จ” รุ่นแถวบ่งบอกถึงความเป็นธรรมชาติที่ผู้เขียนระบุของแต่ละรุ่นที่อยู่ในมือ แต่ยังสามารถพูดได้ว่าค่าดังกล่าวคือในเวลาเดียวกันแสดงถึงบทบาทเล่นโดยมีส่วนร่วมของผู้ใช้เป็นบรรณาธิการของ“ต้นฉบับ” เวอร์ชันของBlogStory
ใช่AuthorId
ค่าที่กำหนดอาจถูกใช้ร่วมกันโดยหลายBlogStoryVersion
แถว แต่จริงๆแล้วเป็นข้อมูลชิ้นหนึ่งที่บอกบางอย่างที่มีความสำคัญมากเกี่ยวกับแต่ละเวอร์ชันดังนั้นการทำซ้ำของตัวเลขดังกล่าวจึงเป็นไม่เป็นปัญหา
รูปแบบของคอลัมน์ DATETIME
สำหรับประเภทข้อมูล DATETIME ใช่คุณถูกต้อง“ MySQL ดึงและแสดงค่า DATETIME ในYYYY-MM-DD HH:MM:SS
รูปแบบ '' 'แต่คุณสามารถป้อนข้อมูลที่เกี่ยวข้องในลักษณะนี้ได้อย่างมั่นใจและเมื่อคุณต้องทำแบบสอบถามคุณเพียงแค่ต้อง ใช้ประโยชน์จากฟังก์ชัน DATE และ TIMEในตัวเพื่อแสดงค่าที่เกี่ยวข้องในรูปแบบที่เหมาะสมสำหรับผู้ใช้ของคุณ หรือคุณสามารถดำเนินการจัดรูปแบบข้อมูลชนิดนี้ได้อย่างแน่นอนผ่านโค้ดแอปพลิเคชันของคุณ
ความหมายของBlogStory
การปฏิบัติการ UPDATE
ทุกครั้งที่BlogStory
แถวที่ได้รับความทุกข์ทรมานจากการอัพเดทคุณต้องแน่ใจว่าค่าที่สอดคล้องกันนั้นเป็น“ ปัจจุบัน” จนกว่าการดัดแปลงจะเกิดขึ้นจากนั้นแทรกเข้าไปในBlogStoryVersion
ตาราง ดังนั้นฉันขอแนะนำให้ดำเนินการเหล่านี้ให้สำเร็จภายในการทำธุรกรรมกรดครั้งเดียวเพื่อรับประกันว่าพวกเขาจะได้รับการปฏิบัติในฐานะหน่วยงานที่แบ่งแยกไม่ได้ คุณอาจจ้างทริกเกอร์เช่นกัน แต่พวกเขามักจะทำสิ่งที่ไม่เป็นระเบียบดังนั้นควรพูด
แนะนำVersionId
หรือVersionCode
คอลัมน์
หากคุณเลือก (เนื่องจากสถานการณ์ทางธุรกิจหรือการตั้งค่าส่วนตัว) เพื่อรวมคอลัมน์BlogStory.VersionId
หรือBlogStory.VersionCode
เพื่อแยกความแตกต่างของBlogStoryVersionsคุณควรไตร่ตรองความเป็นไปได้ดังต่อไปนี้:
VersionCode
อาจจะจำเป็นต้องไม่ซ้ำกันใน (i) ทั้งBlogStory
โต๊ะและยังอยู่ใน (ii)BlogStoryVersion
(ii)
ดังนั้นคุณต้องใช้วิธีการทดสอบอย่างระมัดระวังและเชื่อถือได้โดยสมบูรณ์เพื่อสร้างและกำหนดCode
ค่าแต่ละค่า
บางทีที่VersionCode
ค่าอาจจะซ้ำในที่แตกต่างกันBlogStory
เป็นแถว แต่ไม่เคยBlogStoryNumber
ซ้ำพร้อมกับเดียวกัน เช่นคุณอาจมี:
- a BlogStoryNumber
3
- เวอร์ชัน83o7c5c
และพร้อมกัน
- a BlogStoryNumber
86
- เวอร์ชัน83o7c5c
และ
- BlogStoryNumber
958
- 83o7c5c
รุ่น
ความเป็นไปได้ในภายหลังจะเปิดทางเลือกอื่น:
การรักษาVersionNumber
สำหรับBlogStories
, ดังนั้นอาจมี:
- BlogStoryNumber
23
- รุ่น1, 2, 3…
;
- BlogStoryNumber
650
- รุ่น1, 2, 3…
;
- BlogStoryNumber
2254
- รุ่น1, 2, 3…
;
- เป็นต้น
โฮลดิ้ง "ดั้งเดิม" และ "รุ่นต่อมา" ในตารางเดียว
แม้ว่าการรักษาทั้งหมดBlogStoryVersionsในเดียวกันแต่ละฐานตารางเป็นไปได้ผมขอแนะนำว่าไม่ต้องทำเพราะคุณจะได้รับการผสมทั้งสองแตกต่างกัน (ความคิด) ประเภทของข้อเท็จจริงซึ่งทำให้มีผลข้างเคียงที่ไม่พึงประสงค์บน
- ข้อ จำกัด ของข้อมูลและการจัดการ (ที่ระดับตรรกะ) พร้อมด้วย
- การประมวลผลและการจัดเก็บที่เกี่ยวข้อง (ที่ระดับกายภาพ)
แต่หากคุณเลือกที่จะปฏิบัติตามแนวทางนั้นคุณยังคงสามารถใช้ประโยชน์จากแนวคิดที่มีรายละเอียดด้านบนเช่น:
- คอมโพสิต PK ประกอบด้วยคอลัมน์ INT (
BlogStoryNumber
) และคอลัมน์วันที่และเวลา (CreatedDateTime
);
- การใช้ฟังก์ชั่นเซิร์ฟเวอร์เพื่อปรับกระบวนการที่เกี่ยวข้องให้เหมาะสมและ
- ผู้เขียนและบรรณาธิการได้มาบทบาท
เห็นว่าโดยการดำเนินการกับวิธีการดังกล่าวเป็นBlogStoryNumber
ค่าจะถูกทำซ้ำเร็วที่สุดเท่าที่“ใหม่” รุ่นที่มีการเพิ่มตัวเลือกที่และที่คุณสามารถประเมิน (ซึ่งเป็นมากเหมือนกันที่จะกล่าวถึงในส่วนก่อนหน้า) คือการสร้างBlogStory
PK ประกอบด้วยคอลัมน์BlogStoryNumber
และVersionCode
ในลักษณะนี้คุณจะสามารถระบุแต่ละเวอร์ชั่นของBlogStoryได้ และคุณสามารถลองด้วยการรวมกันของBlogStoryNumber
และVersionNumber
เกินไป
สถานการณ์ที่คล้ายกัน
คุณอาจพบคำตอบของฉันสำหรับคำถามของความช่วยเหลือนี้เนื่องจากฉันยังเสนอให้เปิดใช้งานความสามารถทางโลกในฐานข้อมูลที่เกี่ยวข้องเพื่อจัดการกับสถานการณ์ที่คล้ายกัน