database - how do I model subtyping in a relational schema? -


is following db-schema ok?

  • request-table

request-id | type | meta-1 | meta-2 |

this table stores requests each of has unique request-id. type either a, b or c. tell table contains specific request parameters. other have tables respective types. these tables store parameters respective requests. meta-1 additional info timestamps , stuff.

  • type-a-table

request-id | param_x | param_y | param_z

  • type-b-table

request-id | param_i | param_j

  • type-c-table

request-id | param_l | param_m | param_n | param_o | param_p | param_q

the request-id foreign key request-table.


is design normal/best-practice? or there better/smarter way? alternatives?

it somehow feels strange me, having query on request-table find out type-table contains information need, actual query i'm interested in.

for instance imagine method given id should retrieve parameters. method need 2 db-access. - find correct table query - query table parameters

note: in reality have 10 types of requests, i.e. 10 type tables. there many entries in each of tables.

meta-note: find hard come proper title question (one not overly broad). please feel free make suggestions or edit title.

for exclusive types, need make sure rows in 1 type table can't reference rows in other type table.

create table requests (   request_id integer primary key,   request_type char(1) not null      -- use table constrain valid types.     check (request_type in ('a', 'b', 'c', 'd')),   meta_1 char(1) not null,   meta_2 char(1) not null,   -- foreign key constraints don't reference request_id alone. if    -- did, might reference wrong type.    unique (request_id, request_type) ); 

you need apparently redundant unique constraint pair of columns can target of foreign key constraint.

create table type_a (   request_id integer not null,   request_type char(1) not null default 'a'     check (request_type = 'a'),   primary key (request_id),   foreign key (request_id, request_type)      references requests (request_id, request_type) on delete cascade,   param_x char(1) not null,   param_y char(1) not null,   param_z char(1) not null ); 

the check() constraint guarantees 'a' can stored in request_type column. foreign key constraint guarantees each row reference 'a' row in table "requests". other type tables similar.

create table type_b (   request_id integer not null,   request_type char(1) not null default 'b'     check (request_type = 'b'),   primary key (request_id),   foreign key (request_id, request_type)      references requests (request_id, request_type) on delete cascade,   param_i char(1) not null,   param_j char(1) not null ); 

repeat each type table.

i create 1 updatable view each type. views join table "requests" 1 type table. application code uses views instead of base tables. when that, makes sense revoke privileges on base tables. (not shown.)

if don't know type is, there's no alternative running 1 query type, , query select or update.

select request_type requests request_id = 42;   -- returns 'a'. i'd use view type_a_only. update type_a_only set param_x = '!' request_id = 42; 

in own work, it's pretty rare not know type, happen sometimes.


Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -