More Related Content
More from Akio Ishida (7)
PostgreSQLの範囲型と排他制約
- 2. 範囲型とは
• 範囲をあらわすデータ型(そのまんま)
• 開始と終了を持つ
• 含まれているとか、結合・交差とかの演算子が定義さ
れている
• PostgreSQLでは任意の型を元に新しい範囲型を定義で
きる
Developing Time-Oriented Database Applications in SQLではPeriod型、
Temporal Data and the Relational ModelではInterval型と呼ばれているよ
- 5. こうなります
create table members (
birthday date,
period daterange,
name_en text
);
insert into members(birthday, period, name_en) values
('1988-10-20', '[2001-08-26, 2012-05-18]', 'Risa Niigaki'),
('1988-12-23', '[2003-01-19, 2010-12-15]', 'Eri Kamei'),
('1989-11-11', '[2003-01-19, 2013-05-21]', 'Reina Tanaka'),
('1989-07-13', '[2003-01-19,]', 'Sayumi Michishige'),
('1985-02-26', '[2003-01-19, 2007-06-01]', 'Miki Fujimoto'),
...
- 7. こうなります
create table level1 (
level int,
exp_range int4range,
primary key(level),
exclude using gist (exp_range with &&)
);
insert into level1 values
(1, '[0,11)'),
(2, '[11,59)'),
(3, '[59,164)');
- 11. 使用例
-- 二人の在籍期間の重複日数
=# with q(n1, n2, p) as (
select m1.name_en, m2.name_en,
m1.period * m2.period
from members m1
join members m2 on(m1.name_en < m2.name_en)
)
select n1, n2, upper(p) - lower(p)
from q where not isempty(p) order by 3;
n1
|
n2
| ?column?
------------------+-------------------+---------...
Reina Tanaka
| Sayumi Michishige |
3776
Ai Takahashi
| Risa Niigaki
|
3688
Reina Tanaka
| Risa Niigaki
|
3408
Risa Niigaki
| Sayumi Michishige |
3408
- 13. 範囲型のEXCLUDE制約
=# select * from level1;
level | exp_range
-------+------------1 | [0,11)
2 | [11,59)
3 | [59,164)
...
=# insert into level1 values(100, '[11,12)');
ERROR: 重複キーの値が排除制約 "level1_exp_range_excl" に
違反しています
DETAIL: キー (exp_range)=([11,12)) が既存のキー (exp_range)
=([11,59)) と競合しています
- 15. スカラ型と範囲型の組み合わせ
-- gistは標準では = を使えない
create extension btree_gist;
create table level2 (
exp_type int,
level int,
exp_range int4range,
primary key(exp_type, level),
exclude using gist (exp_type with =, exp_range with &&)
);
insert into level2 values
(100, 1, '[0,11)'),
(100, 2, '[11,59)'),
...
(150, 1, '[0,16)'),
(150, 2, '[16,89)'),