1

大きな質問で申し訳ありませんが、情報が少ないと状況を説明できません。
次のようなデータベース システムを設計しました。

CREATE TABLE servers(
    ID bigint primary key not null
    /* other fields of the server */
);
CREATE TABLE producers(
    ID bigint not null,
    ServerID bigint not null,
    /* other field of the producer */
    constraint "PK_producers"
        primary key (ID, ServerID),
    constraint "FK_producer_servers"
        foreign key("ServerID") references "servers"
);
CREATE TABLE records(
    ID bigint primary key,
    ServerID bigint not null,
    ProducerID bigint not null
    /* other fields of record */
    constraint "FK_records_servers"
        foreign key("ServerID") references "servers"
    constraint "FK_records_producers"
        foreign key("ServerID", "ProducerID") references "producers"
);

CREATE TABLE groups(
    ID bigint not null primary key,
    GroupName nvarchar(50) not null,
    Permissions int not null
    /* other fields of the group */
);
CREATE TABLE users(
    ID bigint not null primary key,
    UserName nvarchar(50) not null unique,
    Permissions int not null
    /* other fields of user */
);
CREATE TABLE users_in_groups(
    UserID bigint not null,
    GroupID bigint not null,
    constraint "PK_users_in_groups" primary key (UserID, GroupID),
    constraint "FK_uig_users" foreign key("UserID") references "users",
    constraint "FK_uig_groups" foreign key("GroupID") references "groups"
);

データはrecordsfromに追加されproducers、各プロデューサーは 1 日あたり 500 ~ 2000 レコードを提供する可能性があり、server通常、それぞれに 2 ~ 4 のプロデューサーがあり、3 ~ 6 のサーバーがあるのは完全に正常です。ご覧recordsのとおり、テーブルは非常に急速に成長しています (私は定期的にいくつかのデータをアーカイブし、データベースを縮小しますが、recordsテーブルには通常 100000 を超えるレコードがあります)。

ここで私の質問は次の
とおりです。ユーザーが現在属しているグループと管理者によって適用された権限に基づいて、ユーザーが異なる権限を持っていることがわかるように、各ユーザーが異なるアイテムに対して異なる権限を持つことができるように、このシステムを進化させる必要があります( serverproducerおよびrecord) ユーザーがアイテムに対する明示的なアクセス許可を持っている場合はそのアクセス許可を使用する方法で、それ以外の場合は親からのアクセス許可と少なくともユーザーのグローバル アクセス許可を使用します。たとえば、 へのユーザー権限は、その 、その、そのまたは ユーザーに定義されたrecord権限に適用される権限から示されます。recordproducerserver

最初の回避策として、次のようにユーザーとさまざまなオブジェクト間の関係を提供する関係テーブルを実装すると思います。

CREATE TABLE user_server_permissions(
    UserID bigint not null,
    ServerID bigint not null,
    Permissions int not null,
    constraint "PK_usp" primary key ("UserID", "ServerID"),
    constraint "FK_usp_users" foreign key ("UserID") references "users",
    constraint "FK_usp_server" foreign key ("ServerID") references "servers"
);
CREATE TABLE user_producer_permissions(
    UserID bigint not null,
    ServerID bigint not null,
    ProducerID bigint not null,
    Permissions int not null,
    constraint "PK_upp" primary key ("UserID", "ServerID", "ProducerID"),
    constraint "FK_upp_users" foreign key ("UserID") references "users",
    constraint "FK_upp_server" foreign key ("ServerID") references "servers"
    constraint "FK_upp_producer" foreign key ("ServerID", "ProducerID") references "producers"
);
CREATE TABLE user_record_permissions(
    UserID bigint not null,
    RecordID bigint not null,
    Permissions int not null,
    constraint "PK_urp" primary key ("UserID", "ServerID"),
    constraint "FK_urp_users" foreign key ("UserID") references "users",
    constraint "FK_urp_record" foreign key ("RecordID") references "records"
);

しかし、このアプローチを使用すると、パフォーマンスが大幅に低下します。これは、私が使用するメインテーブルでrecordsあり、管理者がレコードに特別なアクセス許可を設定し、ほとんどのレコードがそのアクセス許可を使用する必要があるというまれな状態ですが、producerこの手法を使用して複数のテーブルをチェックする必要があるためですrecordsテーブルへの各アクセス。たとえば、次のような単純なクエリ:

SELECT * FROM "records" WHERE /* Some condition */ AND record_is_accessible( "ID" )

複数のクライアントに応答できるはずのサーバーを強制終了します!
ほとんどのクライアントは MSSQL を DBMS として使用していますが、MySQL や ORACLE を使用するケースはほとんどありません。

タスクを達成する方法を教えてくれる人はいますか!?

4

1 に答える 1

2

一見したところ、簡単な解決策は、アクセス許可用に 3 つの個別のテーブルを持たないことです。代わりに、これを持っているでしょう

CREATE TABLE user_entity_permissions(
    UserID bigint not null,
    EntityID bigint not null,
    EntityType int not null,
    Permissions int not null,
    constraint "PK_usp" primary key ("UserID", "EntityID"),
    constraint "FK_usp_users" foreign key ("UserID") references "users"
    --- Third FK constraint ---
    );

次に、必要に応じて 3 番目の Fk 制約を形成します。たとえば、サーバーに EntityType = 1、Producer --> 2、Record --> 3、EntityId および EntityType = 1 のサーバーへの参照などを指定するとします。 ..

このようにして、EntityType を使用してアクセス許可の優先度を並べ替えることもできます (たとえば、最初に 1、次に 2、次に 3)。

于 2012-10-23T11:06:56.257 に答える