2

言う、Userたくさん持っていDevicesます。つまり、Device.user_id references User.id.

ユーザーとデバイスの関係に「アクティブ」ステータスを追加する必要があります。これは、 aUserが 'active' を 1 つしか持てないことを意味しDeviceます。

-- 補遺

私は物事を明確にする必要があるようです。

  • AUserは実際には を持たないこともDevice、 を 1 つDevice、または複数持つこともできDeviceます。
  • Deviceowning を持つことができますが、所有してUserはなりません。
  • その「所有権」はその参照Device.user_id references User.idです。
  • User.idおよびDevice.idは唯一の PK であり、変更してはなりません (したがって、複合 PK はありません)
  • Aは'active'を 1 つ以上User持つことはできませんが、 にすることもできますが、そうでない場合は、これが所有する の1 つを参照する必要があります。DeviceNULLNULLDeviceUser

-- 補遺を終了

2 つのアプローチを想像できますが、どちらも非常に簡単です。

  1. active_device_idにフィールドを追加しUserますUser.active_device_id references Device.id
  2. エンティティにBoolean-type フラグを追加します。Device

最も一般的なクエリは次のとおりです。

  • 指定された のアクティブDeviceを選択しますUser
  • 所有者に対してcurrentDeviceがアクティブかどうかを確認しUserます。

めったに使用されませんが、非常に重要なのは次のとおりです。

  • Device所有者に対して特定の をアクティブにしますUser(そして、他Userの のデバイスを非アクティブにします)。
  • 特定の の所有権を変更しDeviceます。

最初のアプローチには 2 つの注意事項があります。

  • user1アクティブ デバイスが に設定されてdevice1いますdevice1が、所有者はuser2です。
  • user1との両方user2が同じアクティブdeviceになっています (ただし、フィールドの一意の制約によって簡単に修正できますUser.active_device_id

2 次元のアプローチDeviceでは、1 つの に対して複数のアクティブな が発生する可能性がありUserます。

両方のアプローチの他の欠点は何ですか?

...そして、何を選択する必要があり、その理由は? :)

4

4 に答える 4

1

DBMS については触れていませんが、ほとんどの DBMS は部分インデックスを作成する可能性があり、これはそれらの完璧な使用例のようです。

デバイステーブルがどのように見えるか少し混乱していますが、構造を想定しています:

create table device
(
   device_id           integer not null,
   user_id             integer not null,
   is_active_for_user  boolean, 
   primary key (device_id, user_id)
);

次のインデックスを使用して、各ユーザーがアクティブなデバイスを 1 つだけ持つようにすることができます (Postgres 構文、他の DBMS には部分インデックスを定義する他の構文があります)。

create unique index idx_unique_active_device 
    on device (user_id)
    where is_active_for_user;
于 2013-10-03T14:09:04.520 に答える
1

私は間違いなく最初のアプローチ、active_device_id を使用します。

これにより、ユーザーごとに1つのアクティブなデバイスのみが保証され、すべてのユーザーでアクティブなデバイスIDの一意性がオプションで保証されます。

この方法では、すべてのクエリが非常に簡単です。

于 2013-10-03T13:28:49.530 に答える
0

ユーザーごとに1 つの一意のデバイスを適用しようとしている場合、必要なのは、テーブルdeviceId内の参照列に対する一意の制約だけです。userフラグは必要ありません。

デバイス
------
ID

ユーザー
------
ID
deviceId (fk、一意の制約)

David のアプローチに従えば、ユーザーごとにアクティブなデバイスが 1 つだけという保証はありません。UNIQUEユーザーごとに 1 つのデバイスを保証するための制約が必要です。

これにより、重複するデバイスが許可されます。

CREATE TABLE device (
  `id` int,
  PRIMARY KEY(`id`)
) ENGINE=INNODB;

INSERT INTO device (`id`)
VALUES (1), (2);

CREATE TABLE user (
  `id` int, 
  `active_device_id` int,
  INDEX (`active_device_id`),
    FOREIGN KEY (`active_device_id`)
    REFERENCES `device`(`id`)
) ENGINE=INNODB;

INSERT INTO user (`id`, `active_device_id`)
VALUES (1, 1), (2, 1);

各ユーザーが一意のデバイスUNIQUEを持つという保証を追加します。

CREATE TABLE device (
  `id` int,
  PRIMARY KEY(`id`)
) ENGINE=INNODB;

INSERT INTO device (`id`)
VALUES (1), (2);

CREATE TABLE user (
  `id` int, 
  `active_device_id` int,
  INDEX (`active_device_id`),
  UNIQUE (`active_device_id`),
    FOREIGN KEY (`active_device_id`)
    REFERENCES `device`(`id`)
) ENGINE=INNODB;

INSERT INTO user (`id`, `active_device_id`)
VALUES (1, 1), (2, 1);
-- Duplicate entry '1' for key 'active_device_id_2': 
于 2013-10-03T13:33:16.437 に答える