การออกแบบโครงสร้างฐานข้อมูลมิตรภาพ: ฉันควรใช้คอลัมน์ที่มีหลายค่าหรือไม่


9

ว่าฉันมีตารางที่เรียกว่าUser_FriendListซึ่งมีลักษณะดังต่อไปนี้:

CREATE TABLE User_FriendList (
    ID ...,
    User_ID...,
    FriendList_IDs...,
    CONSTRAINT User_Friendlist_PK PRIMARY KEY (ID)
);

และให้เราสมมติว่าตารางดังกล่าวถือข้อมูลต่อไปนี้:

 + ---- + --------- + --------------------------- +
 | ID | User_ID | Friendlist_ID             |
 + ---- + --------- + --------------------------- +
 | 1 | 102 | 2: 15: 66: 35: 26: 17: |
 + ---- + --------- + --------------------------- +
 | 2 | 114 | 1: 12: 63: 33: 24: 16: 102 |
 + ---- + --------- + --------------------------- +
 | 3 | 117 | 6: 24: 52: 61: 23: 90: 97: 118 |
 + ---- + --------- + --------------------------- +

หมายเหตุ: “การ:” (ลำไส้ใหญ่) เป็นตัวคั่นเมื่อระเบิดใน PHP arrayเป็น

คำถาม

ดังนั้น:

  • นี่เป็นวิธีที่สะดวกในการ "เก็บ" IDsของFriendListหรือไม่

  • หรือแทนฉันควรจะมีแต่ละแถวมีเพียงหนึ่งเดียวที่FriendIdคุ้มค่าในแต่ละของพวกเขาและเมื่อฉันต้องเรียกแถวทั้งหมดของกำหนดรายชื่อเพียงแค่ทำแบบสอบถามเหมือนSELECT * FROM UserFriendList WHERE UserId = 1?


3
ฉันแนะนำให้คุณอ่านนี้: stackoverflow.com/questions/3653462/…
tombom

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

ฉันคิดว่าcodedodle.com/2014/12/social-network-friends-database.htmlอาจเป็นหนึ่งในโซลูชันที่ดีที่สุด
Gupta

คำตอบ:


19

การจัดการข้อมูลแต่ละชิ้น

สมมติว่าในโดเมนธุรกิจของคุณ

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

จากนั้นแต่ละ datum เฉพาะที่รวบรวมในFriendlist_IDsคอลัมน์ที่มีหลายค่าจะแสดงข้อมูลแยกต่างหากที่มีความหมายที่แน่นอนมาก ดังนั้นคอลัมน์ดังกล่าว

  • นำมาซึ่งข้อ จำกัด ที่ชัดเจนและกลุ่มที่เหมาะสม
  • คุณค่าของมันมีศักยภาพที่จะถูกจัดการแยกต่างหากโดยใช้วิธีการดำเนินการเชิงสัมพันธ์หลาย ๆ อย่าง

คำตอบสั้น ๆ

ดังนั้นคุณควรเก็บรักษาแต่ละFriendlist_IDsค่าใน (ก) คอลัมน์ที่รับเฉพาะค่าหนึ่ง แต่เพียงผู้เดียวต่อแถวใน (ข) ตารางที่แสดงให้เห็นถึงความคิดระดับประเภทสมาคมที่สามารถเกิดขึ้นระหว่างผู้ใช้คือเป็นเพื่อน -as ฉันจะเป็นตัวอย่างในส่วนต่อไปนี้ -

ด้วยวิธีนี้คุณจะสามารถจัดการ (i) ตารางดังกล่าวว่าเป็นความสัมพันธ์ทางคณิตศาสตร์และ (ii) คอลัมน์กล่าวว่าเป็นแอตทริบิวต์ความสัมพันธ์ทางคณิตศาสตร์- มากเท่ากับ MySQL และภาษา SQL ของใบอนุญาต -

ทำไม?

เนื่องจากรูปแบบเชิงสัมพันธ์ของข้อมูลที่สร้างโดยDr. E. F. Coddต้องการให้มีตารางที่ประกอบด้วยคอลัมน์ที่เก็บค่าหนึ่งโดเมนของโดเมนหรือประเภทต่อแถวที่เกี่ยวข้อง ดังนั้นการประกาศตารางที่มีคอลัมน์ที่มีมากกว่าหนึ่งค่าของโดเมนหรือประเภทของคำถาม (1) ไม่ได้แสดงถึงความสัมพันธ์ทางคณิตศาสตร์และ (2) จะไม่อนุญาตให้ได้รับประโยชน์ที่เสนอในกรอบทฤษฎีดังกล่าวข้างต้น

การสร้างแบบจำลองมิตรภาพระหว่างผู้ใช้ : การกำหนดกฎเกณฑ์สภาพแวดล้อมทางธุรกิจก่อน

ฉันขอแนะนำให้เริ่มกำหนดขนาดฐานข้อมูล - ก่อนสิ่งอื่นใด - โครงสร้างแนวคิดที่สอดคล้องกันโดยอาศัยอำนาจตามคำจำกัดความของกฎเกณฑ์ทางธุรกิจที่เกี่ยวข้องซึ่งในบรรดาปัจจัยอื่น ๆ จะต้องอธิบายประเภทของความสัมพันธ์ที่มีอยู่ระหว่างประเภทนิติบุคคลที่เกี่ยวข้องและคุณสมบัติของพวกเขา; เช่น:

  • ผู้ใช้จะถูกระบุโดยส่วนใหญ่ของเขาหรือเธอหมายเลขผู้ใช้
  • ผู้ใช้จะถูกระบุสลับด้วยการผสมผสานของเขาหรือเธอFirstName , นามสกุล , เพศและวันเกิด
  • ผู้ใช้จะถูกระบุโดยสลับกันของเขาหรือเธอชื่อผู้ใช้
  • ผู้ใช้เป็นผู้ขอเป็นศูนย์หนึ่งหรือหลายมิตรภาพ
  • ผู้ใช้เป็นผู้รับของศูนย์หนึ่งหรือหลายมิตรภาพ
  • มิตรภาพจะถูกระบุเป็นหลักโดยการรวมกันของตนRequesterIdและAddresseeId

ไดอะแกรม IDEF1X ของที่เก็บข้อมูล

ในลักษณะนี้ฉันสามารถรับไดอะแกรมIDEF1X 1 ที่แสดงในรูปที่ 1ซึ่งรวมกฎส่วนใหญ่ที่กำหนดไว้ก่อนหน้านี้:

รูปที่ 1. ไดอะแกรมมิตรภาพของผู้ใช้ IDEF1X

ในฐานะที่เป็นภาพผู้ขอและผู้รับมี denotations ที่แสดงบทบาทที่ดำเนินการโดยเฉพาะผู้ที่มีส่วนร่วมในให้เพื่อน

ที่เป็นเช่นนั้นมิตรภาพประเภทนิติบุคคล portrays ประเภทความสัมพันธ์ของหลายต่อหลายคน (M: N) อัตราส่วน cardinality ที่สามารถเกี่ยวข้องกับการที่แตกต่างกัน ocurrences ของเดียวกันนิติบุคคลประเภทคือผู้ใช้ เช่นนี้มันเป็นตัวอย่างของการสร้างแบบคลาสสิกที่เรียกว่า "Bill of Materials" หรือ "Parts Explosion"


1 นิยามการรวมสำหรับการสร้างแบบจำลองข้อมูล ( IDEF1X ) เป็นเทคนิคที่แนะนำอย่างสูงซึ่งก่อตั้งขึ้นเป็นมาตรฐานในเดือนธันวาคม 1993 โดยสถาบันมาตรฐานและเทคโนโลยีแห่งชาติของสหรัฐอเมริกา(NIST) มันมีพื้นฐานมาจาก (a) เนื้อหาทางทฤษฎียุคแรกที่ประพันธ์โดยผู้สร้าง แต่เพียงผู้เดียวของโมเดลเชิงสัมพันธ์คือดร. EF Codd ; บน (b)มุมมองเอนทิตีของข้อมูลที่พัฒนาโดย Dr. PP Chen ; และ (c) เทคนิคการออกแบบฐานข้อมูลแบบลอจิคัลสร้างโดย Robert G. Brown


การออกแบบเชิงตรรกะของ SQL-DDL

จากนั้นจากแผนภาพ IDEF1X ที่นำเสนอข้างต้นการประกาศการจัดเรียง DDL เช่นเดียวกับที่ตามมานั้นเป็น "ธรรมชาติ" มากกว่า:

-- You should determine which are the most fitting 
-- data types and sizes for all the table columns 
-- depending on your business context characteristics.

-- At the physical level, you should make accurate tests 
-- to define the mostconvenient INDEX strategies based on 
-- the pertinent query tendencies.

-- As one would expect, you are free to make use of 
-- your preferred (or required) naming conventions. 

CREATE TABLE UserProfile ( -- Represents an independent entity type.
    UserId          INT      NOT NULL,
    FirstName       CHAR(30) NOT NULL,
    LastName        CHAR(30) NOT NULL,
    BirthDate       DATE     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,
        GenderCode,
        BirthDate
    ),
    CONSTRAINT UserProfile_AK2 UNIQUE (Username) -- Single-column ALTERNATE KEY.
);

CREATE TABLE Friendship ( -- Stands for an associative entity type.
    RequesterId     INT      NOT NULL,
    AddresseeId     INT      NOT NULL, -- Fixed with a well-delimited data type.
    CreatedDateTime DATETIME NOT NULL,
    --
    CONSTRAINT Friendship_PK            PRIMARY KEY (RequesterId, AddresseeId), -- Composite PRIMARY KEY.
    CONSTRAINT FriendshipToRequester_FK FOREIGN KEY (RequesterId)
        REFERENCES UserProfile (UserId),
    CONSTRAINT FriendshipToAddressee_FK FOREIGN KEY (AddresseeId)
        REFERENCES UserProfile (UserId)
);

ในแบบนี้:

  • ตารางฐานแต่ละตารางแสดงประเภทเอนทิตีแต่ละรายการ
  • แต่ละคอลัมน์ย่อมาจากที่พักเพียงอย่างเดียวของแต่ละประเภทนิติบุคคล
  • เฉพาะพิมพ์ข้อมูลได้รับการแก้ไขในแต่ละคอลัมน์เพื่อรับประกันว่าทุกค่าจะมีเป็นของเฉพาะและกำหนดไว้เป็นอย่างดีชุดไม่ว่าจะเป็น INT, DATETIME, CHAR ฯลฯ .; และ
  • มีการกำหนดค่าหลายข้อ จำกัดb (ประกาศ) เพื่อให้แน่ใจว่าการยืนยันในรูปแบบของแถวที่เก็บไว้ในตารางทั้งหมดตรงตามกฎทางธุรกิจที่กำหนดที่สคีแนวคิด

ข้อดีของคอลัมน์ที่มีค่าเดียว

ดังที่แสดงให้เห็นว่าคุณสามารถทำได้เช่น:

  • ใช้ประโยชน์จากReferential Integrity ที่บังคับใช้โดยระบบการจัดการฐานข้อมูล (DBMS สำหรับความกะทัดรัด) สำหรับFriendship.AddresseeIdคอลัมน์เนื่องจากบังคับให้เป็นคีย์ต่างประเทศ (FK สำหรับความกะทัดรัด) ที่ทำให้การอ้างอิงกับUserProfile.UserIdคอลัมน์รับประกันว่าทุกค่าชี้ไปยังแถวที่มีอยู่

  • สร้างคอมโพสิตคีย์หลัก (PK) สร้างขึ้นจากการรวมกันของคอลัมน์ที่(Friendship.RequesterId, Friendship.AddresseeId)ช่วยในการแยกแยะความแตกต่างอย่างหรูหราแถวแทรกและธรรมชาติปกป้องพวกเขาเป็นเอกลักษณ์

    แน่นอนนี่หมายความว่าสิ่งที่แนบมาของคอลัมน์พิเศษสำหรับค่าตัวแทนที่กำหนดโดยระบบ (เช่นการตั้งค่าด้วยคุณสมบัติตัวตนใน Microsoft SQL Server หรือด้วยแอตทริบิวต์AUTO_INCREMENTใน MySQL) และการช่วยเหลือ INDEX นั้นไม่จำเป็นเลย

  • จำกัด ค่าที่เก็บรักษาไว้ในFriendship.AddresseeIdประเภทข้อมูลที่แม่นยำc (ซึ่งควรจับคู่เช่นที่สร้างขึ้นสำหรับUserProfile.UserIdในกรณีนี้ INT) ปล่อยให้ DBMS ดูแลการตรวจสอบอัตโนมัติที่เกี่ยวข้อง

    ปัจจัยนี้สามารถช่วยในการ (a) ใช้ประโยชน์จากฟังก์ชั่นชนิดในตัวที่สอดคล้องกันและ (b) ปรับการใช้พื้นที่ดิสก์ให้เหมาะสม

  • เพิ่มประสิทธิภาพการดึงข้อมูลในระดับกายภาพโดยการกำหนดค่าดัชนีย่อยขนาดเล็กและรวดเร็วสำหรับFriendship.AddresseeIdคอลัมน์เนื่องจากองค์ประกอบทางกายภาพเหล่านี้สามารถช่วยได้อย่างมากในการเร่งการสืบค้นที่เกี่ยวข้องกับคอลัมน์ดังกล่าว

    แน่นอนว่าคุณสามารถทำได้เช่นวาง INDEX แบบคอลัมน์Friendship.AddresseeIdเดียวสำหรับคนเดียวแบบหลายคอลัมน์ที่ครอบคลุมFriendship.RequesterIdและFriendship.AddresseeIdหรือทั้งสองอย่าง

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

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

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


a , b , c , dเห็นได้ชัดเมื่อทำงานกับแพลตฟอร์ม SQL (เช่น Firebirdและ PostgreSQL ) ที่สนับสนุนการสร้าง DOMAIN (คุณลักษณะเชิงสัมพันธ์ที่โดดเด่น) คุณสามารถประกาศคอลัมน์ที่ยอมรับค่าที่อยู่ในนั้นเท่านั้น (ข้อ จำกัด และบางครั้งเหมาะสม แบ่งปันแล้ว) DOMAINs


แอปพลิเคชันอย่างน้อยหนึ่งโปรแกรมที่แบ่งปันฐานข้อมูลอยู่ระหว่างการพิจารณา

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

ประโยชน์เพิ่มเติมของคอลัมน์ที่มีค่าเดียว: ส่วนขยายโครงสร้างฐานข้อมูลนั้นง่ายกว่ามาก

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

ความก้าวหน้าของสถานการณ์: การรวมแนวคิดสถานะมิตรภาพ

เนื่องจากมิตรภาพสามารถพัฒนาไปตามกาลเวลาคุณอาจต้องติดตามปรากฏการณ์ดังกล่าวดังนั้นคุณจะต้อง (i) ขยายสคีแนวคิดและ (ii) ประกาศตารางเพิ่มเติมอีกสองสามตารางในเค้าโครงแบบตรรกะ ดังนั้นให้เราจัดระเบียบกฎเกณฑ์ทางธุรกิจถัดไปเพื่อวิเคราะห์การรวมใหม่:

  • มิตรภาพถือแบบหนึ่งต่อหลายFriendshipStatuses
  • FriendshipStatusถูกระบุเป็นหลักโดยการรวมกันของตนRequesterIdมันAddresseeIdและSpecifiedDateTime
  • ผู้ใช้ระบุศูนย์หนึ่งหรือหลายFriendshipStatuses
  • สถานะรายการจัดประเภทเป็นศูนย์หนึ่งหรือหลายFriendshipStatuses
  • สถานะจะถูกระบุโดยส่วนใหญ่ของStatusCode
  • สถานะการระบุสลับกันโดยตัวของมันชื่อ

ไดอะแกรม IDEF1X เพิ่มเติม

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

รูปที่ 2. ไดอะแกรมสถานะมิตรภาพ IDEF1X

การเพิ่มโครงสร้างเชิงตรรกะ

หลังจากนั้นเราสามารถยืดโครงร่าง DDL ด้วยการประกาศต่อไปนี้:

--
CREATE TABLE MyStatus ( -- Denotes an independent entity type.
    StatusCode CHAR(1)  NOT NULL,
    Name       CHAR(30) NOT NULL,
    --
    CONSTRAINT MyStatus_PK PRIMARY KEY (StatusCode),
    CONSTRAINT MyStatus_AK UNIQUE      (Name) -- ALTERNATE KEY.
); 

CREATE TABLE FriendshipStatus ( -- Represents an associative entity type.
    RequesterId       INT      NOT NULL,
    AddresseeId       INT      NOT NULL,
    SpecifiedDateTime DATETIME NOT NULL,
    StatusCode        CHAR(1)  NOT NULL,
    SpecifierId       INT      NOT NULL,
    --
    CONSTRAINT FriendshipStatus_PK             PRIMARY KEY (RequesterId, AddresseeId, SpecifiedDateTime), -- Composite PRIMARY KEY.
    CONSTRAINT FriendshipStatusToFriendship_FK FOREIGN KEY (RequesterId, AddresseeId)
        REFERENCES Friendship  (RequesterId, AddresseeId), -- Composite FOREIGN KEY.
    CONSTRAINT FriendshipStatusToMyStatus_FK   FOREIGN KEY (StatusCode)
        REFERENCES MyStatus    (StatusCode),
    CONSTRAINT FriendshipStatusToSpecifier_FK  FOREIGN KEY (SpecifierId)
        REFERENCES UserProfile (UserId)      
);

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

  • ที่เหมาะสมRequesterIdและAddresseeIdคุณค่า - นำมาจากแถวที่เกี่ยวข้อง - Friendship;

  • มูลค่าใหม่และมีความหมายStatusCodeถอนออกจากMyStatus.StatusCode-;

  • INSERTion ที่แน่นอนทันทีคือ - SpecifiedDateTimeใช้ฟังก์ชั่นเซิร์ฟเวอร์เพื่อให้คุณสามารถเรียกคืนและเก็บรักษาไว้ในลักษณะที่เชื่อถือได้ -; และ

  • SpecifierIdค่าที่จะแสดงให้เห็นตามลำดับUserIdที่เข้ามาใหม่FriendshipStatusเข้าสู่ระบบ -ideally ด้วยความช่วยเหลือของแอปของคุณ (s) facilities-

ในระดับนั้นขอให้เราสมมติว่าMyStatusตารางแนบข้อมูลต่อไปนี้ - ด้วยค่า PK ที่ (a) ผู้ใช้ปลายทาง, แอปโปรแกรมเมอร์และ DBA เป็นมิตรและ (b) เล็กและเร็วในแง่ของไบต์ที่ระดับการใช้งานจริง -:

 + ------------ + ----------- +
 | StatusCode | ชื่อ       |
 + ------------ + ----------- +
 | R | ร้องขอ |
 + ------------ + ----------- +
 | A | ยอมรับ |
 + ------------ + ----------- +
 | D | ปฏิเสธ |
 + ------------ + ----------- +
 | B | Bloqued |
 + ------------ + ----------- +

ดังนั้นFriendshipStatusตารางอาจเก็บข้อมูลดังแสดงด้านล่าง:

 + + ------------- ------------- + --------------------- ---- + + ------------ ------------- +
 | RequesterId | ที่อยู่รหัส | SpecifiedDateTime        | StatusCode | SpecifierId |
 + + ------------- ------------- + --------------------- ---- + + ------------ ------------- +
 | พ.ศ. 2293 พ.ศ. 2291 2016-04-01 16: 58: 12.000 | R | พ.ศ. 2293
 + + ------------- ------------- + --------------------- ---- + + ------------ ------------- +
 | พ.ศ. 2293 พ.ศ. 2291 2016-04-02 09: 12: 05.000 | A | พ.ศ. 2291
 + + ------------- ------------- + --------------------- ---- + + ------------ ------------- +
 | พ.ศ. 2293 พ.ศ. 2291 2016-04-04 10: 57: 01.000 | B | พ.ศ. 2293
 + + ------------- ------------- + --------------------- ---- + + ------------ ------------- +
 | พ.ศ. 2293 พ.ศ. 2291 2016-04-07 07: 33: 08.000 | R | พ.ศ. 2291
 + + ------------- ------------- + --------------------- ---- + + ------------ ------------- +
 | พ.ศ. 2293 พ.ศ. 2291 2016-04-08 12: 12: 09.000 | A | พ.ศ. 2293
 + + ------------- ------------- + --------------------- ---- + + ------------ ------------- +

ในขณะที่คุณสามารถดูก็อาจกล่าวได้ว่าFriendshipStatusตารางจุดมุ่งหมายของการประกอบการอนุกรมเวลา


โพสต์ที่เกี่ยวข้อง

คุณอาจสนใจใน:

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