ユーザーとグループを表す必要があります。グループは他のグループ内にネストできます。
(私の設計の選択ではありません。私は別のシステムを複製しており、この動作を模倣する必要があります。その実装の詳細にアクセスすることはできず、ユーザードキュメントにのみアクセスします。)
グループを他のグループに入れると、階層が作成されます。別のグループに配置されたあるグループのユーザーは、両方のグループのアクセス権限を取得します。たとえば、Executives
グループをAccounting
グループに配置すると、Executives
グループのユーザーは両方のグループの権限を享受できます。ただし、Accounting
グループにのみ配置されたユーザーは、そのグループの特権のみを利用できます。 (確かに、ありそうな現実的なビジネスシナリオではなく、単なる不自然な例です。)
このようなもの ERD図 と思います。
私は 多対多の関係 のuser_
からgroup_
の処理方法を知っています。しかし、私にはわかりません。
このグループ内のグループは「再帰的な」関係と見なされますか?正しい専門用語は何ですか?
関連する可能性があります: SQL Serverの再帰クエリ および 特定する再帰SQLクエリ
自己参照キー(隣接リスト、階層関係、再帰的関係)に直行するだけです。「最も適切で適切な」用語が何であるかはわかりませんが、これらのいずれもポイントに到達する必要があります。メンバーシップテーブルとともに、「プリンシパル」または「ロール」テーブルとなるものについて十分にチューニングされたオーディエンス)。私はSQL Serverからインスピレーションを得ていますが、PostgreSQLも\du
または\dg
で示されているような独自のセキュリティ管理のためにこれを行います。とはいえ、組み込みのセキュリティ管理でこれをすべて処理しようとすることを検討することにも価値があるかもしれません。
CREATE ROLE accounting;
GRANT SELECT ON account TO accounting;
CREATE ROLE executives;
GRANT accounting TO executives;
CREATE USER cto_bill;
GRANT executives TO cto_bill;
「CTO Bill」は、SELECT
テーブルから、account
ロールを介してexecutives
ロールまで、accounting
から、すべて完全にボックス。アプリケーションがチェーン化された権限を知る必要がある場合、\du
またはpg_catalog
のpg_auth_members
およびpg_roles
テーブルに対するクエリの形式を介して公開できます。
SELECT r.rolname, r.rolsuper, r.rolinherit,
r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,
r.rolconnlimit, ARRAY( SELECT b.rolname
FROM pg_catalog.pg_auth_members m
INNER JOIN pg_catalog.pg_roles b
ON ( m.roleid = b.oid )
WHERE m.member = r.oid ) as memberof
FROM pg_catalog.pg_roles r
WHERE r.rolcanlogin = 'f'
ORDER BY 1;
完全な解決策が必要であると思われる場合は、 this のようなスキーマを構築できます。
CREATE TABLE Principal
(
Principal_PK SERIAL NOT NULL,
Name VARCHAR( 128 ) NOT NULL,
PasswordHash BYTEA,
Type CHAR( 1 ) NOT NULL
);
ALTER TABLE Principal
ADD CONSTRAINT PK__Principal
PRIMARY KEY ( Principal_PK );
ALTER TABLE Principal
ADD CONSTRAINT UQ__Principal__Name
UNIQUE ( Name );
ALTER TABLE Principal
ADD CONSTRAINT CK__Principal__Type
CHECK ( Type IN ( 'U', 'G' ) );
CREATE TABLE PrincipalMembership
(
PrincipalMembership_PK SERIAL NOT NULL,
Principal_FK INTEGER NOT NULL,
IsMemberOfPrincipal_FK INTEGER NOT NULL,
DateCreated TIMESTAMP NOT NULL
);
ALTER TABLE PrincipalMembership
ADD CONSTRAINT PK__PrincipalMembership
PRIMARY KEY ( PrincipalMembership_PK );
ALTER TABLE PrincipalMembership
ADD CONSTRAINT FK__PrincipalMembership__Principal
FOREIGN KEY ( Principal_FK )
REFERENCES Principal ( Principal_PK );
ALTER TABLE PrincipalMembership
ADD CONSTRAINT FK__PrincipalMembership__IsMemberOfPrincipal
FOREIGN KEY ( IsMemberOfPrincipal_FK )
REFERENCES Principal ( Principal_PK );
ALTER TABLE PrincipalMembership
ADD CONSTRAINT UQ__PrincipalMembership__Principal__IsMemberOfPrincipal
UNIQUE ( Principal_FK, IsMemberOfPrincipal_FK );
ALTER TABLE PrincipalMembership
ALTER COLUMN DateCreated SET DEFAULT ( NOW() );
INSERT INTO Principal ( Name, PasswordHash, Type )
VALUES ( 'accounting', NULL, 'G' ),
( 'executives', NULL, 'G' ),
( 'cto_bill', E'\\x00', 'U' );
INSERT INTO PrincipalMembership ( Principal_FK, IsMemberOfPrincipal_FK )
SELECT p.Principal_PK, m.Principal_PK
FROM ( SELECT 'executives', 'accounting'
UNION ALL SELECT 'cto_bill', 'executives' ) pl ( Name, IsMemberOf )
INNER JOIN Principal p
ON p.Name = pl.Name
INNER JOIN Principal m
ON m.Name = pl.IsMemberOf;
次に、 Recursive CTE など、必要なほとんどすべてのツリー走査メソッドを使用して、さまざまなメンバーシッププロパティを決定します。
;WITH RECURSIVE cte_Membership AS (
SELECT p.Principal_PK, p.Name, pm.IsMemberOfPrincipal_FK
FROM Principal p
LEFT JOIN PrincipalMembership pm
ON pm.Principal_FK = p.Principal_PK
UNION ALL
SELECT c.Principal_PK, c.Name, pm.IsMemberOfPrincipal_FK
FROM cte_Membership c
INNER JOIN Principal p
ON p.Principal_PK = c.IsMemberOfPrincipal_FK
INNER JOIN PrincipalMembership pm
ON pm.Principal_FK = p.Principal_PK )
SELECT m.Name, p.Name AS IsMemberOf
FROM cte_Membership m
LEFT JOIN Principal p
ON p.Principal_PK = m.IsMemberOfPrincipal_FK
ORDER BY m.Name, IsMemberOf;
編集:自己参照キーと再帰トラバーサルを含むソリューションの管理は、注意が急がれないと急いで爆乳になる可能性があることを言及することはおそらく非常に価値があります循環参照が行われないようにするために取られました。 (誤って)accountingをexecutivesグループのメンバーにすると、サンプルのCTEは機能しなくなり、階層の複雑さが増すため、そのようなエラーが発生する可能性が高くなります。率直に言って、循環参照からの保護は少しお尻の苦痛ですが、このような場合、ストアドプロシージャでこれらのテーブルに対してCRUD操作を非表示にすると非常に役立ちます。既存のソリューションを複製しようとしているので、そのシステムには、新しいソリューションに適したリトマステストの開発に役立つガイドラインがいくつかあります。
まず始めに-group_
の自己関係は1対多ですかよろしいですか? Executives
はAccounting
のメンバーであるだけでなく、Penthouse Restaurant
のメンバーでもあるように思えます。同様に、Accounting
にはExecutives
だけでなく Trolls
も含まれます。これは多対多であり、ユーザー/グループの相互作用に関する問題はすでに解決しています。ここでも同じように解決します。
1対多であることが確実である場合は、SQLに いくつかの異なる実装 のツリーがあります。