Yabu.log

色々勉強するブログです。

プログラマのためのSQL 読書会(16)に参加

16、17、18章を読みました。

比較演算子

  • !=
  • not=

は標準SQLではない

  • postgresは比較演算子をオーバーライドして独自で定義可能
  • mysqlでは”A”と"A "が同じものと見なされるので、厳密比較する時はlikeを使う

文字コードとソート順の話

mysqlではソートする時にキャラセットを与えることができる(ただしindexは使えなくなる)

mysqlのデータ長と表示幅について

mysqlだとint(4)の(4)はデータ長ではなく、表示幅。 char(4)の(4)はデータ長を表す。混ざっているので非常にややこしい

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11118528146 https://qiita.com/masarufuruya/items/ccf51e917a5cbf8890a3

疑問:int(4)で10000を出せるの? ->普通に出せた。

行式の比較

訳註に

Oracle,PostgreSQL,MySQLなどがサポートしてある

とあるが、他のプラットフォームだとSQLServerは対応しておらず、DB2は対応してある。

(a,b,c)= (x,y,z)(a=x) and (b=y) and (c=z)と同じ結果になる

postgres=# select (1,2,3) = (1,2,3);
 ?column? 
----------
 t
(1 row)

postgres=# select (1,2,3) = (1,2,4);
 ?column? 
----------
 f
(1 row)

postgres=# select (1,2,3) = (1,2,null);
 ?column? 
----------
 
(1 row)

postgres=# select (1,2,3) = (1,3,null);
 ?column? 
----------
 f
(1 row)

IS [NOT] DISTINCT FROM演算子

比較演算子の一種だがnullをあたいのように使える<>の動きをする。 すでに存在しているDISTINTとFROMという単語を使っているのが気になる。 mysqlなら<=>という比較演算子を使える模様。

select 1 as A,2 as B,1 is distinct from 2 as result union all
select 1 as A,1 as B,1 is distinct from 1 as result union all
select null as A,1 as B,null is distinct from 1 as result union all
select null as A,null as B,null is distinct from null as result union all

a | b | result 
---+---+--------
1 | 2 | t
1 | 1 | f
  | 1 | t
  |   | f

INDEXにnull

oracleではnullが入るとindexが効かなくなる。 sqlserverdb2はnullが入ってもindexが使える

バッチ処理で動作が遅くなる原因になる。

IS NULL

SQL92では行式も利用できる。postgresで検証してみた

postgres=# select (true,false,null) is  null;
 ?column? 
----------
 f
(1 row)

postgres=# select (null,null,null) is  null;
 ?column? 
----------
 t
(1 row)

行式の各カラムの結果が全てnullの場合、is nullはtrueとなる。

IS [NOT] NORMALIZED述語

Unicode文字列が4つの正規系(D,C,KD,KC)のいずれかに該当するか否かを調べる

http://nomenclator.la.coocan.jp/unicode/normalization.htm

  • 式がunicodeの正規化をされているか検証できる。
  • それはSQLでやることなのか?というツッコミが入った。
  • postgresで試してみたが構文エラーになり使えなかった

BNF Grammar for ISO/IEC 9075-2:2003 - Database Language SQL (SQL-2003) SQL/Foundation

ここのBNFの定義を見る限り2003年から入ったっぽい(sql99にはなかった)

余談:normalizedとかnormalizationがテーブルの正規化の意味と被ってしまい非常にググラビリティーが低い。

case式

case式はADAのものを参考にしているらしい。(意外)

  • 単純case式
  • 検索case式

単純case式でnullは扱えないので検索case式を利用する。

select case null
when null then 'ぬる'
else 'ぬるじゃないよ' end;

case      
----------------
ぬるじゃないよ
(1 row)

select case 
  when null is null then 'ぬる'
  else 'ぬるじゃないよ' end;

case 
------
ぬる
(1 row)

random

  • テストデータを作る時に使う
  • 昔から文句を言われている?

SQLのrandomは暗号などには使えないため、専用に用意されているものを利用すること。

スミステルルール

"スミステルルール"でググると、この本にしか登場しない

"スミステルルール" - Google 検索

ローゼンシュタインの特性関数

とりあえずcase式を使え。

18章の編集ミス?

kindle版では訳註は後ろに纏められているが、この章だけ訳註1が本文中に書かれている。

全体を通しての感想

  • 数値型はあまり意識せず使っていた。
  • 行の比較を知らなかった
    • 冗長なAndをひたすら続ける条件式をよく書いていたが、短くかけるのではないか、と思った。
  • 18章はクヌースの本の引用がある箇所とかは難しくてよくわからなかった。(小並感)