ページ

2012/11/25

[SQLearning][SQLite]テーブルの変更と削除

SQL ゼロからはじめるデータベース操作を教材にしてSQLiteを学ぶ
SQL学習連載「SQLearning」の第4回です。

前回: [SQLearning][SQLite]データ型と制約の指定 | DevAchieve
第3回は「テーブルの変更と削除」についてです。

カラムの追加

以下の CREATE 文で生成されるテーブルを元に解説していきます。
CREATE TABLE products (
    id          INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    name        TEXT    NOT NULL UNIQUE,
    description TEXT    NULL,
    price       INTEGER NOT NULL,
    discount    INTEGER NOT NULL DEFAULT 0,
    reg_date    TEXT    NOT NULL DEFAULT CURRENT_DATE
);
このテーブルにカラムを追加するには以下のように記述します。
ALTER TABLE <テーブル名> ADD <カラム名> <型> <制約>;
ALTER TABLE products
    ADD bar_code TEXT NOT NULL DEFAULT '000000000000000';
カラムは常に末尾に追加されます。
CREATE TABLE 構文とは異なり、以下のような制約があります。
  • 追加されるカラムは PRIMARY KEY 制約, UNIQUE 制約を持つことができません。
  • 追加されるカラムは デフォルト値に固定値以外の値(CURRENT_TIME, CURRENT_DATE, CURRENT_TIMESTAMP, 式)を持つことができません。
  • 追加されるカラムに NOT NULL 制約が指定されている場合は NULL 以外のデフォルト値が設定されている必要があります。
  • 外部キー制約が有効で、REFERENCES 句とともにカラムが追加された場合、追加されたカラムはデフォルト値に NULL を持たなくてはなりません。
※ CHECK 制約を追加する際は既存の列に対してテストされないことに注意してください。
これは CHECK 制約に違反するデータを含むテーブルになりうることを意味します。
SQLite の今後のバージョンでは追加される CHECK 制約を検証するように変更されるかもしれません。

カラムが追加されたデータベースは SQLite Ver.3.1.3 以前のバージョンで読めなくなります。

テーブル名の変更

テーブル名を変更するには以下のように記述します。
ALTER TABLE <テーブル名> RENAME TO <新しいテーブル名>;
テーブル名を変更した際に外部キー制約が有効ならば
REFERENCES 句に指定されていたテーブル名は新しいテーブル名に自動的にリネームされます。

SQLite Query Language: ALTER TABLE

テーブルの削除

テーブルを削除するには以下のように記述します。
DROP TABLE <テーブル名>;
テーブルに関連付けられたすべてのインデックスとトリガも削除されます。
DROP TABLE IF EXISTS <テーブル名>;
IF EXISTS を記述すれば存在しないテーブルの削除を試みることによるエラーを防ぐことができます。

次回

次回は「SELECT文の基礎」を予定しています。

SQL ゼロからはじめるデータベース操作 (CD-ROM付) (プログラミング学習シリーズ)
SQL ゼロからはじめるデータベース操作 (CD-ROM付) (プログラミング学習シリーズ)

2012/11/24

[SQLearning][MySQL]テーブルの変更・削除

SQL ゼロからはじめるデータベース操作を教材にしてMySQLを学ぶ
SQL学習連載「SQLearning」の第4回です。
前回: [SQLearning][MySQL]データ型・制約の指定 | DevAchieve
第4回は「テーブルの変更・削除」についてです。

カラムの追加

前回同様、以下のテーブルを元に解説していきます。
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| name        | varchar(255) | NO   | UNI | NULL    |                |
| description | text         | YES  |     | NULL    |                |
| price       | int(11)      | NO   |     | NULL    |                |
| tax_free    | tinyint(1)   | NO   |     | 0       |                |
| reg_date    | datetime     | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
このテーブルにカラムを追加するには以下のように記述します。
ALTER TABLE <テーブル名> ADD <追加するカラム名> <型> <制約>;
ALTER TABLE products
    ADD bar_code varchar(255) NOT NULL DEFAULT '0-000000-000000' AFTER tax_free;
カラムの追加位置は AFTER で指定します。未指定の場合は末尾に追加されます。
先頭に追加する場合は以下のように FIRST で指定します。
ALTER TABLE products
    ADD products_type_id int(11) NOT NULL DEFAULT 0 COMMENT '商品タイプ' FIRST;
また、複数追加する場合は以下のようにカンマ区切りで記述します。
ALTER TABLE products
    ADD receipt_name varchar(255) NOT NULL COMMENT 'レシート表示名' AFTER name,
    ADD url varchar(255) NULL DEFAULT NULL COMMENT '商品ページURL' AFTER description;

カラムの変更

カラム名、カラムの型や制約を変更する場合は以下のように記述します。
ALTER TABLE <テーブル名> CHANGE <古いカラム名> <新しいカラム名> <型> <制約>;
ALTER TABLE products
    CHANGE url homepage_url varchar(255) NULL DEFAULT NULL COMMENT '商品ホームページURL';

カラムの型や制約だけを変更したい場合は以下のように記述します。
ALTER TABLE <テーブル名> MODIFY <変更するカラム名> <型> <制約>;
ALTER TABLE products
    MODIFY bar_code varchar(13) NOT NULL DEFAULT '0000000000000' AFTER id;
AFTER でカラムの順番も変更することもできます。
Oracleの独自実装の互換性対応のため実装されているようです。

カラムのデフォルト値を削除したい場合は以下のように記述します。
ALTER TABLE <テーブル名> ALTER <カラム名> DROP DEFAULT;
ALTER TABLE products
    ALTER bar_code DROP DEFAULT;

カラムのデフォルト値を設定したい場合は以下のように記述します。
ALTER TABLE <テーブル名> ALTER <カラム名> SET DEFAULT <デフォルト値>;
ALTER TABLE products
    ALTER bar_code SET DEFAULT '0000000000000';

カラムの削除

カラムを削除したい場合は以下のように記述します。
ALTER TABLE <テーブル名> DROP <削除するカラム名>;
ALTER TABLE products
    DROP homepage_url;

ADD, ALTER, CHANGE, DROP はカンマで区切ることによって一度に複数の変更を実行することができます。
ALTER TABLE では元テーブルの一時コピーを作成するため一度に変更を実行したほうが良いです。
ほとんどの場合、 ALTER TABLE は元テーブルのテンポラリ コピーを作成する事で起動します。
そのコピー上で変更が行われ、その後元テーブルが削除されて新しいテーブルがリネームされます。
ALTER TABLE が実行している間、他のクライアントが元テーブルを読む事ができます。
新しいテーブルの準備ができるまで更新と書き込みは止められ、
その後更新に失敗する事なく新しいテーブルに自動的にリダイレクトされます。
MySQL :: MySQL 5.1 リファレンスマニュアル :: 12.1.2 ALTER TABLE 構文

AUTO_INCREMENT の値の変更

以下のように記述します。
ALTER TABLE <テーブル名> AUTO_INCREMENT = <値>;
ALTER TABLE products AUTO_INCREMENT = 100;
AUTO_INCREMENT カラム内の最高値以下の値が指定された場合、
MyISAMでは最高値+1にリセットされますが、InnoDBではエラーも出ず、変更もされません。

おまけ: AUTO_INCREMENT の振り直し

挿入と削除を繰り返していると id が歯抜け状態になるので振り直したい時に使えます。
データ不整合を起こす可能性があるのでよく検討してから使用してください。
ALTER TABLE products
    CHANGE id renamed_id int(11);
ALTER TABLE products
    ADD id int(11) NOT NULL AUTO_INCREMENT FIRST,
    ADD PRIMARY KEY(id),
    DROP renamed_id;
単純に id を DROP してから追加しないのは先に DROP すると順序が変わる可能性があるからです。

テーブル名の変更

ALTER TABLE <テーブル名> RENAME TO <新しいテーブル名>
RENAME TABLE <テーブル名> TO <新しいテーブル名>
標準SQLでテーブル名の変更が定義されていないので独自実装で方法が幾つかあります。
MySQL :: MySQL 5.1 リファレンスマニュアル :: 12.1.19 RENAME TABLE 構文

データベースエンジンの変更

ALTER TABLE <テーブル名> ENGINE = <エンジン名>;
ALTER TABLE products ENGINE = InnoDB;

デフォルト文字セットの変更

ALTER TABLE <テーブル名> DEFAULT CHARSET = <文字コード名>;

MySQL :: MySQL 5.1 リファレンスマニュアル :: 12.1.2 ALTER TABLE 構文

テーブルの削除

DROP TABLE [IF EXISTS] <テーブル名>;
DROP TABLE products;
DROP TABLE IF EXISTS products;
IF EXISTS を記述すれば存在しないテーブルの削除を試みることによるエラーを防ぐことができます。

次回

次回は「SELECT文の基礎」について予定しています。
SQL ゼロからはじめるデータベース操作 (CD-ROM付) (プログラミング学習シリーズ)
SQL ゼロからはじめるデータベース操作 (CD-ROM付) (プログラミング学習シリーズ)

2012/11/18

[CSS] ol 要素を使用しないカウントアップするリストを作ってみた

前回のリストマーカー引き続き、CSSで ol タグ相当のCSSクラスを作ってみた。
[CSS]before擬似要素を使って複数行対応のリストマーカーを作ってみた | DevAchieve

また ::before 擬似要素を使っているので CSS3 扱い。
IE8ではコロンをひとつにしないと動かない。
css/list.cssCSS list-counter sample page
カウント部分は前回と同じく複数行対応になっている。
Generated content, automatic numbering, and lists にある通り、
本記事では count になっている identifier を初期化しなければならない。
/**
 * list-counter base class
 */
.counter.init {
    counter-reset: count;
}
.count {
    display: block;
    padding-left: 1em;
}
.count::before {
    counter-increment: count;
    display: block;
    float: left;
    margin-left: -1em;
    width: 1em;
    text-align: center;
}
/**
 * list-counter counter class
 */
.counter.type_decimal .count::before {
    content: counter(count, decimal);
}
.counter.type_decimal_leading_zero .count::before {
    content: counter(count, decimal-leading-zero);
}
.counter.type_lower_roman .count::before {
    content: counter(count, lower-roman);
}
.counter.type_upper_roman .count::before {
    content: counter(count, upper-roman);
}
.counter.type_lower_greek .count::before {
    content: counter(count, lower-greek);
}
.counter.type_upper_greek .count::before {
    content: counter(count, upper-greek);
}
.counter.type_lower_latin .count::before {
    content: counter(count, lower-latin);
}
.counter.type_upper_latin .count::before {
    content: counter(count, upper-latin);
}
.counter.type_lower_alpha .count::before {
    content: counter(count, lower-alpha);
}
.counter.type_upper_alpha .count::before {
    content: counter(count, upper-alpha);
}
.counter.type_armenian .count::before {
    content: counter(count, armenian);
}
.counter.type_georgian .count::before {
    content: counter(count, georgian);
}
upper-greek に関しては W3C の list-style-type プロパティの定義には載っていないのでブラウザ実装依存。
Opera では decimal, Firefox では 空白 になり、Chrome, Safari, IE9では正常に表示される。

モダンブラウザのための最小clearfixハック

CSSハックの中でも最も有名で最も使われているのが clearfix だろう。
CSSハック嫌いの僕でも clearfix の有用性だけは認めざるを得ない。
それでもCSSハックは使いたくないのでできるだけ簡潔な表現にした。

ネタ元はこちら:A new micro clearfix hack – Nicolas Gallagher

IE6/7どころかIE8もサポートしない最強の clearfix である。
IE9 と Chrome, Firefox, Safari, Opera の最新版で動作することを確認済み。
.clearfix::after {
    content: "";
    display: table;
    clear: both;
}

ネタ元の以下の clearfix はIE6+をサポートするので困ったらコッチを使うと良い。
/**
 * A new micro clearfix hack – Nicolas Gallagher
 * http://nicolasgallagher.com/micro-clearfix-hack/
 */
.clearfix:before,
.clearfix:after {
    content: " ";
    display: table;
}

.clearfix:after {
    clear: both;
}

.clearfix {
    *zoom: 1; /* for IE 6/7 only */
}
ちなみにHTML5 Boilerplate: The web's most popular front-end templateでも使われている方法なので安心!

2012/11/13

[CSS]before擬似要素を使って複数行対応のリストマーカーを作ってみた

ul 要素などに指定できる list-style-type には種類に制限があるので
好きなリストマーカーを自由に設定できるように
::before擬似要素を使ってリストマーカー用のクラスを作ってみた。
css/list.css
もちろんテキストが複数行になってもインデントが揃っている。
サンプルページ:CSS list-marker sample page
.marker {
    display: block;
    padding-left: 1em;
}
.marker::before {
    content: "";
    display: block;
    float: left;
    margin-left: -1em;
    width: 1em;
    text-align: center;
}
::before擬似要素でブロック要素を生成して float: left; で要素の左に並べる。
要素を padding-left: 1em; で左に間を空けて margin-left: -1em; で左に戻す。
width: 1em; で text-align: center; を指定しておけば半角文字のマーカーが真ん中に来て良い感じになる。

::before という書き方は擬似クラスと擬似要素が多くなった CSS3 からの書き方なので
IE8 では対応してないので :before と書く必要がある。ちなみに IE6/7はサポートすらされていない。

上のクラスを指定しただけではリストマーカーは表示されないので以下のように指定する。
content には画像や属性値を指定することもできる。
.marker.type_disc::before {
    content: "・";
}
.marker.type_filled_circle::before {
    content: "●";
}
.marker.type_outline_circle::before {
    content: "○";
}
.marker.type_filled_square::before {
    content: "■";
}
.marker.type_outline_square::before {
    content: "□";
}
.marker.type_filled_diamond::before {
    content: "◆";
}
.marker.type_outline_diamond::before {
    content: "◇";
}
.marker.type_filled_star::before {
    content: "★";
}
.marker.type_outline_star::before {
    content: "☆";
}
.marker.type_filled_triangle::before {
    content: "▲";
}
.marker.type_outline_triangle::before {
    content: "△";
}
.marker.type_filled_inverted_triangle::before {
    content: "▼";
}
.marker.type_outline_inverted_triangle::before {
    content: "▽";
}


2012/11/10

PHP で ASCII コードを利用して CSS の list-style-type を再現する

CSS の list-style-type は ul 要素や ol 要素などに指定することができて、
以下のように表示したければ
  1. あいうえお
  2. かきくけこ
  3. さしすせそ
以下のように指定します。
ol {
    list-style-type: upper-alpha;
}
<ol>
    <li>あいうえお</li>
    <li>かきくけこ</li>
    <li>さしすせそ</li>
</ol>
しかし、このABCなどのリストマーカー部分をリスト部分とは異なるデザインにしたい場合、
特に表示位置、色、大きさを調節したい場合はリストでは難しくなります。

HTML/CSSでは難しいのですが、動的なサイトだったためPHPで書くことができました。
リストマーカー部分が数値であれば簡単に for ループのインデックスが使えるのですが
リストマーカーが英字なので少しどうしたものかと思いました。
パッと思い浮かんだ選択肢は、アルファベットを持った配列を定義しておきインデックスで配列の要素を出力、
またはアルファベットを文字列で持ちインデックスでsubstrで1文字だけ出力、という2つ。

定義するのがめんどくさいし、ダサい実装でどうしたものかと考えていたら
C言語の入門書でアスキーコードを利用したことを思い出しました。
PHPでアスキーコードを利用したことがなかったのですが、
C言語でできることはPHPでもできるだろと探してみたらありました。

PHPでアスキーコードを利用する方法!

<?php
for($i = 0; $i < 26; $i++){
    echo chr(ord('A') + $i) . '.';
}
?>
chrがアスキーコードから文字を返してくれて、ordが文字のアスキーコードを返してくれます。

2012/11/03

[書評]Android SDK開発のレシピ

AndroidSDK開発のレシピ―104個のレシピで学ぶAndroidアプリ開発の極意
塚田翔也
秀和システム
発売日:2010-08
ブクログでレビューを見る»
Androidのちょっと変わったネタをレシピとして紹介している本。
ある程度アプリを開発できるようになって
変わったネタを求めている開発者にオススメ。

Android SDK開発のレシピ 第二版 もオススメです。
http://www.amazon.co.jp/o/ASIN/4798035297/wada811-22/ref=nosim/
「Android SDK開発のレシピ」という本を書きました。 - gabuchanの日記

Android SDK開発のレシピ 第2版
塚田翔也
秀和システム
発売日:2012-09
ブクログでレビューを見る»
Androidのベストプラクティスが詰まった本。
レシピ形式で幅広い項目を扱っているので読めば大抵のことはできるようになる。
普通の本では扱われない設定やショートカット、ツールの使い方なども紹介されていて良い。
サンプル用のアプリやコードが公開されているのでとても参考になる。
「Android SDK開発のレシピ」が第2版になりました。 - gabuchanの日記

第1版の時はまだAndroid初心者だったので変わったネタも使い道がなくて、
汎用的なネタが多かったAndroid SDK逆引きハンドブックに取って代わられて本棚の肥やしになっていました。
第2版ではだいぶ網羅的になっていて、初心者でも役に立つようなレシピが多かったです。
サンプルコードもGitHub(https://github.com/gabu/gabubon2)で公開されているし、
レシピ自体が一つのAndroidアプリになっていて凄く参考になりました!
読むだけでAndroidのハマりポイントを回避していけるので感謝です!

余談ですが、第2版の表紙を見た時、JellyBeanだからこんな表紙なのかと思ったら第1版からだったんですね。
AndroidSDK開発のレシピ―104個のレシピで学ぶAndroidアプリ開発の極意Android SDK開発のレシピ