9. テーブルの操作
操作 GRASS SQLite
列の追加 v.db.addcol ALTER TABLE … ADD COLUMN…
列名の変更 v.db.renamecol 非対応*
列の削除 db.dropcol / v.db.dropcol 非対応*
テーブル名の変更 g.rename ALTER TABLE … RENAME TO …
テーブルの削除 g.remove DROP TABLE …
*やろうと思えばできる(新テーブル作成⇒データのコピー⇒元テーブル削除⇒テーブル名の変更)
テーブルの操作は、GRASSコマンドとSQLite(SQL文)のどちらからでもできます。
列名の変更と列の削除はSQLiteでサポートしていないので、何かと便利です。
リファレンスにも書いてあります。
db.dropcol is a front-end to db.execute to allow easier usage
with a special workaround for the SQLite driver to support column drop.
http://grass.osgeo.org/grass64/manuals/db.dropcol.html
GRASSで扱う上で、レイヤ名(テーブル名)や列名の制限がいくつかあります。
・半角英数字とアンダーバーのみサポート
・最初の文字はアルファベット
・レイヤ名の字数は、198文字までは大丈夫でした。
・SQLの構文で使用する語句は使用できません。 例)SELECT
・列名には大文字と小文字の区別がありません。(NAME=name)
10. SQLiteの型
データ型 種類 GRASSの型
NULL 空文字 null
INTGER 整数(8~64ビット) integer
REAL 浮動小数点数(64ビット) double precision
TEXT テキスト型(UTF-8 / UTF-16BE / UTF-16LE) varchar(n)
BLOB バイナリ型 -
型の名前は、一般的な名称なら理解してくれます。( INT, FLOAT, DOUBLE, VARCHAR etc.)
...型の定義はGRASSに合わせるのが吉です。
SQLiteに格納される値のデータ型は5種類。
なお、BLOB型はGRASS GISで扱えないので、
この型の列を含むテーブルをGRASSで操作するとエラーが出ます。
GRASS 6.4.3 (HKD_J2K)> v.db.renamecol map=hoge column=old_column,new_column
WARNING: SQLite driver: unable to parse decltype: blob
WARNING: SQLite driver: column 'blob', SQLite type 4 is not supported
Datatypes In SQLite Version 3 http://www.sqlite.org/datatype3.html
11. UPDATE hoge
SET int = 0, real = 0, text = 0;
UPDATE hoge
SET
int = 2014/6/27,
real = 2014/6/27,
text = 2014/6/27;
UPDATE hoge
SET
int = 2014/6/27,
real = 1.0*2014/6/27,
text = '2014/6/27';
SQLiteの型
列毎にデフォルトの型を定義することができますが、それぞれのセルには
独立した型のデータを格納することができてしまいます。
一応、列の定義に応じた型で格納されていますが、、、
型ごちゃまぜでもSQLite的には問題ありません。
SQLを介して演算をする場合は、文字列でも数値とみなして計算しようとします。
整数のみの演算の場合、整数型にも注意が必要です。
12. 何ができる?
SQL文を使って高度なデータ選択、抽出、それを元にしたデータの更新ができます。
○条件による絞込み(WHERE)
・LIKE演算子でのパターンマッチング 例)WHERE city_name LIKE “%上%”
(正規表現でのマッチング(REGEXP演算子)はデフォルトでは使えない)
○データのグループ化(GROUP BY)
・同じ条件の行を一つにまとめて集計する 例)GROUP BY city_name
SELECT * FROM cityborder
WHERE city_name LIKE "%上%"
SELECT
'○○'||substr(city_name,-1) AS city_type,
count(city_name) AS count
FROM cityborder
GROUP BY city_type
例)市区町村の最後の一文字でグループ化して数を集計
例)名称に「上」を含む市区町村を抽出
13. ○他のテーブルとの結合(LEFT JOIN, INNER JOIN)
SELECT *
FROM nationalcensus_mesh
LEFT JOIN landuse_mesh
ON landuse_mesh.meshID = nationalcensus_mesh.key_code;
例)メッシュデータの結合(国勢調査と土地利用)
LEFT JOIN
国勢調査メッシュデータ 土地利用メッシュデータ
SQLiteで利用できる結合はLEFT、INNER、CROSS、NATURALの四種類です。
⇒RIGHT JOIN,FULL OUTER JOINには対応していないので、結合の順序に注意が必要です。
何ができる?
15. ○選択結果の利用(サブクエリ)
ALTER TABLE landuse_mesh
ADD COLUMN Population integer; --列を追加
UPDATE landuse_mesh
SET Population =
(SELECT Population
FROM nationalcensus_mesh
WHERE landuse_mesh.meshID = nationalcensus_mesh.key_code
);
例)属性データに他のテーブルのデータを挿入(データの更新:UPDATEステートメント)
・・・
CREATE INDEX landuse_mesh_meshID ON landuse_mesh (meshID);
CREATE INDEX nationalcensus_mesh_key_code ON nationalcensus_mesh (key_code);
○インデックスの設定
・SQLiteでは、各カラムにインデックスを設定することができます。
これによって、結合やサブクエリを介した更新などが劇的に早くなる場合があります。
例)上記のUPDATE例の場合(landuse_mesh:114,100行 nationalcensus_mesh:180,222行)
処理時間 インデックス作成前:約2時間15分 ⇒インデックス作成後:1.18秒
⇒ユニークインデックス作成(CREATE UNIQUE INDEX)後:1.08秒
何ができる?