2012-10-23 83 views
1

對不起,有一個很大的問題,但我無法用較少的信息來解釋我的情況。
我設計了一個數據庫系統,該系統是這樣的:文件系統像DBMS中的權限

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" 
); 

的數據將被從producers加入records並且每個生產商可以提供500〜2000記錄每天每個server通常有2〜4生產,它是完全正常的有3〜6臺服務器。正如你所看到的records表增長非常快(我定期存檔一些數據和縮小數據庫,但records表通常有> 100000條記錄)。

現在我的問題是:
正如你看到的用戶有不同的權限,根據他們目前屬於哪個組以及管理員應用了哪些權限,現在我必須以每個用戶可能擁有的方式推進此係統對不同項目(server,producerrecord)的不同權限以如下方式進行:如果用戶具有對項目的明確權限,則使用該權限,否則使用來自父項的權限和至少全部用戶的權限。例如,用戶對record的權限將通過應用於該record,其producerserver或爲用戶定義的權限的權限指示。

作爲第一個解決辦法,我想我會實現關係表提供用戶與各種對象之間的關係如下:

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的情況。

現在任何人都可以指導我完成任務!

+0

什麼* kind *的SQL? – podiluska

+0

請發佈一個會「殺死」你的服務器的查詢的例子。 –

回答

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 --- 
    ); 

現在你要相應地塑造你的三鍵約束(如果需要) 例如讓我們說你給服務器的的EntityType = 1,生產者 - > 2,記錄 - > 3 然後ENTITYID和的EntityType = 1個引用服務器等等...

這種方式,您還可以使用的EntityType排序您的權限的優先級(例如1第一,然後2,然後3)

+0

非常感謝您的快速回答,我會檢查它,並讓您知道您的方法的差異,我測試了像您的解決方案,但我不知道爲什麼我放棄它。我認爲我有一些問題,或者我很愚蠢,沒有任何理由就忽略它! :) – BigBoss

+0

沒問題!如果你絆倒另一個問題,請告訴我。我很樂意與你一起工作。 –