これらの要件を達成するために使用できる設計パターンの1つは、Entity-Attribute-Value（EAV）パターンです。EAVパターンでは、共通フィールドは1つのテーブル（「エンティティ」テーブル）に保存され、タイプ固有のフィールドは別のテーブル（「属性」テーブル）に値と格納されます。これにより、柔軟で拡張可能なデータモデルが可能になります。

以下は、EAVパターンを使用してさまざまなタイプのイベントをPostgresデータベースに保存する方法の例です。
1.まず、すべてのイベントの共通フィールドを保存するテーブルを作成します。
`` `
テーブルイベントを作成します（
    IDシリアルプライマリキー、
    タイトルテキストはnullではなく、
    説明テキストはnullではなく、
    日付タイムスタンプはnullではありません
）;
`` `

2.次に、イベントのタイプ固有のフィールドを保存するテーブルを作成します。
`` `
テーブルevent_attributesを作成する（
    IDシリアルプライマリキー、
    event_id integerはnullではありません、
    属性_NAMEテキストはnullではありません、
    属性_valueテキストはnullではありません、
    制約event_attributes_event_id_fkey外部キー（event_id）参照イベント（id）delete cascade
）;
`` `
この表では、各行は特定のイベントの特定の属性を表します。「属性_NAME」列には、属性の名前（例：「トピック」または「いいね」））が含まれ、「属性_Value」列には属性の値が含まれます。

3.新しいタイプのイベントを追加するには、適切な「属性_NAME」および「属性_Value」値を使用して、「event_attributes」テーブルに新しい行を追加するだけです。たとえば、「トピック」属性と「いいね！」属性を持つコメントイベントを追加するには、次のことを行うことができます。
`` `
 - 新しいコメントイベントを追加します
イベントに挿入（タイトル、説明、日付）値（「私のコメントイベント」、「これは私のコメントです」、now（））;
 - 「トピック」属性を追加します
intersing event_attributes（event_id、aTtiont_name、aTtiont_value）values（1、 'topic'、 'my topic'）;
 - 「いいね」属性を追加します
intersing event_attributes（event_id、aTtiont_name、aTtribute_value）値（1、「いいね」、 '10'）;
`` `

4.すべてのイベントを照会するには、そのタイプに関係なく、Joinクエリを使用できます。
`` `
[イベント]を選択します
イベントから
event.id.id = event_attributes.event_idでevent_attributesを左に参加します
events.date descによる注文;
`` `

このクエリは、すべてのイベントを、属性とともに日付でソートします。

このEAVパターンを使用して、「event_attributes」テーブルに制約を追加するだけで、タイプ固有の列にヌル制約を強制しないことができます。また、データモデルはモジュラーで拡張可能であるため、データベースのダウンタイムなしで新しいタイプのエンティティを簡単に追加できます。
One possible design pattern that can be used to achieve these requirements is the Entity-Attribute-Value (EAV) pattern. In the EAV pattern, the common fields are stored in one table (the "entity" table), and the type-specific fields are stored in another table (the "attribute" table), along with their values. This allows for a flexible and extensible data model.

Here is an example of how you could use the EAV pattern to store Events of different types in a Postgres database:
1. First, create a table to store the common fields of all Events:
``` 
CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    description TEXT NOT NULL,
    date TIMESTAMP NOT NULL
);
``` 

2. Next, create a table to store the type-specific fields of Events:
``` 
CREATE TABLE event_attributes (
    id SERIAL PRIMARY KEY,
    event_id INTEGER NOT NULL,
    attribute_name TEXT NOT NULL,
    attribute_value TEXT NOT NULL,
    CONSTRAINT event_attributes_event_id_fkey FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE
);
``` 
In this table, each row represents a specific attribute of a specific Event. The "attribute_name" column contains the name of the attribute (e.g., "topic" or "number of likes"), and the "attribute_value" column contains the value of the attribute.

3. To add a new type of Event, you would simply add new rows to the "event_attributes" table with the appropriate "attribute_name" and "attribute_value" values. For example, to add a Comment Event with a "topic" attribute and a "number of likes" attribute, you could do the following:
``` 
-- Add a new Comment Event
INSERT INTO events (title, description, date) VALUES ('My Comment Event', 'This is my comment', NOW());
-- Add the "topic" attribute
INSERT INTO event_attributes (event_id, attribute_name, attribute_value) VALUES (1, 'topic', 'My Topic');
-- Add the "number of likes" attribute
INSERT INTO event_attributes (event_id, attribute_name, attribute_value) VALUES (1, 'number of likes', '10');
``` 

4. To query all Events, regardless of their type, you could use a JOIN query:
``` 
SELECT events.*, event_attributes.attribute_name, event_attributes.attribute_value
FROM events
LEFT JOIN event_attributes ON events.id = event_attributes.event_id
ORDER BY events.date DESC;
``` 

This query will return all Events, along with their attributes, sorted by date.

Using this EAV pattern, you can enforce NOT NULL constraints on the type-specific columns by simply adding the constraints to the "event_attributes" table. And because the data model is modular and extensible, you can easily add new types of Entities without downtime for the database.