One approach to designing a modular data model for storing entities of different types in PostgreSQL is to use the Entity-Attribute-Value (EAV) pattern. This pattern involves creating a table with a generic structure that can store data for multiple entity types. In this table, each row represents an attribute-value pair for an entity, where the attribute is a string identifying a specific piece of data and the value is the actual data for that attribute.

To illustrate this approach, let's consider the example of storing different types of events, where each event has a title and a description, and additional properties depending on its type. For simplicity, let's assume we have three types of events: 'Comment', 'Announcement', and 'Reminder'.

To implement the EAV pattern in this scenario, we can create the following tables:

sql

CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    description TEXT NOT NULL,
    created_at TIMESTAMP NOT NULL
);

CREATE TABLE event_attributes (
    id SERIAL PRIMARY KEY,
    event_id INTEGER NOT NULL,
    attribute TEXT NOT NULL,
    value TEXT NOT NULL,
    FOREIGN KEY (event_id) REFERENCES events (id) ON DELETE CASCADE
);
The events table has columns for the common fields of all events: id, title, description, and created_at. The id column is a primary key, and the title, description, and created_at columns have NOT NULL constraints to ensure that every event has these properties.

The event_attributes table has columns for the type-specific properties of events. It has a foreign key reference to the events table to associate each attribute-value pair with a specific event. The attribute column is a string that identifies the type-specific property, and the value column stores the actual data for that property.

To store a comment event, we can insert the following rows into the two tables:

sql

INSERT INTO events (title, description, created_at)
VALUES ('Comment on post', 'This is a comment', now());

INSERT INTO event_attributes (event_id, attribute, value)
VALUES (1, 'topic', 'Database design'),
       (1, 'likes', '5');
In this example, we created an event with a title and a description, and added two attributes specific to comment events: 'topic' and 'likes'.

To retrieve all events, regardless of their type, we can use a simple SELECT query:

css

SELECT e.id, e.title, e.description, e.created_at, a.attribute, a.value
FROM events e
LEFT JOIN event_attributes a ON e.id = a.event_id
ORDER BY e.created_at DESC;
This query retrieves all events from the events table and all their associated attributes from the event_attributes table. By using a LEFT JOIN, we ensure that events without attributes are also included in the result set.

To add a new type of event, we can simply add new rows to the event_attributes table with new attribute names and values. We don't need to modify the schema of the events table, so there is no downtime required.

Overall, the EAV pattern is a flexible and extensible design pattern for storing entities of different types in a PostgreSQL database. However, it has some drawbacks, including the potential for slower queries and the lack of type safety for the attributes. Therefore, it's important to carefully consider the trade-offs before adopting this pattern.
แนวทางหนึ่งในการออกแบบโมเดลข้อมูลแบบแยกส่วนสำหรับจัดเก็บเอนทิตีประเภทต่างๆ ใน PostgreSQL คือการใช้รูปแบบ Entity-Attribute-Value (EAV) รูปแบบนี้เกี่ยวข้องกับการสร้างตารางที่มีโครงสร้างทั่วไปที่สามารถจัดเก็บข้อมูลสำหรับเอนทิตีหลายประเภท ในตารางนี้ แต่ละแถวแสดงถึงคู่แอตทริบิวต์-ค่าสำหรับเอนทิตี โดยที่แอตทริบิวต์คือสตริงที่ระบุชิ้นส่วนของข้อมูลเฉพาะ และค่าคือข้อมูลจริงสำหรับแอตทริบิวต์นั้น เพื่ออธิบายแนวทางนี้ ลองพิจารณาตัวอย่างการจัดเก็บเหตุการณ์ประเภทต่างๆ โดยที่แต่ละเหตุการณ์มีชื่อเรื่องและคำอธิบาย และคุณสมบัติเพิ่มเติมขึ้นอยู่กับประเภทของเหตุการณ์ เพื่อความง่าย สมมติว่าเรามีเหตุการณ์สามประเภท: 'ความคิดเห็น' 'การประกาศ' และ 'การแจ้งเตือน' หากต้องการใช้รูปแบบ EAV ในสถานการณ์นี้ เราสามารถสร้างตารางต่อไปนี้: เหตุการณ์ sql CREATE TABLE ( id SERIAL PRIMARY KEY, title TEXT NOT NULL, description TEXT NOT NULL, create_at TIMESTAMP NOT NULL ); สร้างตาราง event_attributes ( id SERIAL PRIMARY KEY, event_id INTEGER NOT NULL, คุณลักษณะ TEXT NOT NULL, ค่า TEXT NOT NULL, FOREIGN KEY (event_id) REFERENCES events (id) ON DELETE CASCADE ); ตารางเหตุการณ์มีคอลัมน์สำหรับช่องทั่วไปของเหตุการณ์ทั้งหมด: id, title, description และ create_at คอลัมน์ id เป็นคีย์หลัก และคอลัมน์ชื่อ คำอธิบาย และคอลัมน์ create_at ไม่มีข้อจำกัด NULL เพื่อให้แน่ใจว่าทุกเหตุการณ์มีคุณสมบัติเหล่านี้ ตาราง event_attributes มีคอลัมน์สำหรับคุณสมบัติเฉพาะประเภทของเหตุการณ์ มีการอ้างอิงคีย์นอกไปยังตารางเหตุการณ์เพื่อเชื่อมโยงแต่ละคู่ค่าแอตทริบิวต์กับเหตุการณ์เฉพาะ คอลัมน์แอตทริบิวต์คือสตริงที่ระบุคุณสมบัติเฉพาะประเภท และคอลัมน์ค่าจะเก็บข้อมูลจริงสำหรับคุณสมบัตินั้น ในการจัดเก็บเหตุการณ์ความคิดเห็น เราสามารถแทรกแถวต่อไปนี้ลงในสองตาราง: sql INSERT INTO events (title, description, create_at) VALUES ('Comment on post', 'This is a comment', now()); แทรกลงใน event_attributes (event_id, คุณลักษณะ, ค่า) ค่า (1, 'หัวข้อ', 'การออกแบบฐานข้อมูล'), (1, 'ชอบ', '5'); ในตัวอย่างนี้ เราสร้างกิจกรรมที่มีชื่อและคำอธิบาย และเพิ่มแอตทริบิวต์เฉพาะสำหรับกิจกรรมความคิดเห็น: 'หัวข้อ' และ 'ชอบ' หากต้องการดึงข้อมูลเหตุการณ์ทั้งหมด ไม่ว่าจะเป็นประเภทใดก็ตาม เราสามารถใช้แบบสอบถาม SELECT ง่ายๆ ได้: css SELECT e.id, e.title, e.description, e.created_at, a.attribute, a.value FROM events e LEFT JOIN event_attributes a ON e.id = a.event_id สั่งซื้อโดย e.created_at DESC; แบบสอบถามนี้จะดึงเหตุการณ์ทั้งหมดจากตารางเหตุการณ์และแอตทริบิวต์ที่เกี่ยวข้องทั้งหมดจากตาราง event_attributes เมื่อใช้ LEFT JOIN เรารับรองว่าเหตุการณ์ที่ไม่มีแอตทริบิวต์จะรวมอยู่ในชุดผลลัพธ์ด้วย หากต้องการเพิ่มเหตุการณ์ประเภทใหม่ เราสามารถเพิ่มแถวใหม่ลงในตาราง event_attributes ด้วยชื่อแอตทริบิวต์และค่าใหม่ เราไม่จำเป็นต้องแก้ไขสคีมาของตารางเหตุการณ์ ดังนั้นจึงไม่จำเป็นต้องหยุดทำงาน โดยรวมแล้ว รูปแบบ EAV เป็นรูปแบบการออกแบบที่ยืดหยุ่นและขยายได้สำหรับการจัดเก็บเอนทิตีประเภทต่างๆ ในฐานข้อมูล PostgreSQL อย่างไรก็ตาม มีข้อบกพร่องบางประการ รวมถึงโอกาสในการสืบค้นที่ช้ากว่าและการขาดความปลอดภัยของประเภทสำหรับแอตทริบิวต์ ดังนั้นจึงเป็นเรื่องสำคัญที่จะต้องพิจารณาข้อดีข้อเสียอย่างรอบคอบก่อนที่จะใช้รูปแบบนี้
spam fails_task lang_mismatch pii not_appropriate hate_speech sexual_content quality toxicity humor helpfulness creativity violence