※画像はテーブル作成(物理)の様子です。
この記事ではカスタムモジュールでテーブルをデータベースに追加する際に使うhook_schema
という関数のパラメーターについて説明します。hook_schema
のチュートリアルについてはこちらを御覧ください。
hook_schemaの構造
hook_schema
はモジュール内の.install
ファイルの中で定義されます。hook_schema
内では、$schema
という変数の中にテーブルを定義し、最後に$schema
を返すことでテーブルがデータベースに登録されます。
テーブルの宣言
$schema['TABLE_NAME'] =[テーブルの定義];
と書くことでテーブルを宣言します。上記のコードをテーブルごとに書くことで複数のテーブルを$schema
に含めることが出来ます。
$schema['table1']=[...];
$schema['table2']=[...];
その場合は、モジュールをインストールすると$schema
の中で宣言したすべてのテーブルがデータベースに登録されます。
テーブル内のパラメーター
$schema['[テーブル名]']
の直下にくるパラメーターには以下のようなものがあります。
'field'
: カラムの定義(必須)'description'
: テーブルの説明(オプション)'primary keys'
: プライマリーキー(オプション)'unique keys'
: ユニークキー(オプション)'foreign keys'
: 外部キー(オプション)'indexes'
: インデックス(オプション)
以下、それぞれの詳細について解説していきます。
field
field
ではフィールド(カラム)に入るデータの形式を定義します。
さまざまなパラメーターがありますが、type
のみが必須で、残りはオプションです。
ただし、type
がnumeric
のときはprecision
とscale
が、type
がvarchar
のときはlength
が必須になります。
description
: フィールドの説明。 他のテーブルについて言及する場合は、{[テーブル名]}のように{}で囲う必要があります。(筆者注:おそらく見やすさのため。)type
: データ型。Drupalで定められた型名を使うことで、データベースのエンジン固有の型に自動的にマッピングされます。 使える型名は以下の通り。char
varchar
int
float
numeric
text
blob
serial
mysql_type
,pgsql_type
,sqlite_type
等: データベースドライバーに固有のタイプ。例えば、'mysql_type' => 'TIME'
は'pgsql_type' => 'time without time zone'
と同じです。(訳者注: 例えば、MySQLのDATETIME型を使うときは、mysql_type => 'datetime'
と書きます。)size
: データのサイズ。上限量を決めるとともにデータベース固有のデータ型のヒントになります。例えば、データ型がint
でデータサイズがtiny
だと、MySQLではTINYINT
として読み込まれます。使えるサイズ名は以下です。tiny
small
medium
normal
big
データ型とサイズについては こちらに詳しい情報があります。
not null
: trueの場合、空白が許可されます。 デフォルトではfalse
になっています。default
: フィールドのデフォルト値。PHPのデータ型に従って値が識別されるため、''
と'0'
と0
はすべて別モノとして扱われるので注意。タイプがtext
かblob
のフィールドはデフォルト値を持つことが出来ません。length
: データ型がchar
かvarchar
かtext
のフィールドに対して、長さを指定します。他のデータ型に対して指定しても無視されます。varchar
に対しては必須です。unsigned
: データ型がint
かfloat
かnumeric
のデータで下限を0にするか(マイナスを扱わないか)どうかを決めるboolean値。デフォルトではFALSE。他のデータ型のフィールドでは無視される。precision
,scale
: データ型がnumeric
のフィールドに対し、precision
(桁数) とscale
(小数点の右側の桁数)を指定します。両方とも必須です。他のデータ型に対しては設定しても無視されます。serialize
: フィールドがシリアライズされるかどうかを示すboolean値です。binary
: データ型がchar
かvarchar
かtext
のフィールドに対して MySQLが大文字と小文字を区別するバイナリーの照合順序を使うかどうかを指定するboolean値です。他のデータ型では大文字と小文字を区別するのがデフォルトなので無視されます。
'fields' => [
'nid' => [
'description' => 'The {node}.nid this record affects.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
],
description
テーブルとその目的について説明するプレーンテキストの文章です。他のテーブルに言及する場合は{}でテーブル名を囲わなくてはいけません。
'description' => 'Stores per-revision title and body data for each {node}.',
primary key
プライマリーキーを構成する配列。一つ以上のフィールドを指定します。
'primary keys' => ['uid', 'module', 'name'],
unique keys
ユニークキーを定義する連想配列。
'[キー名]' => [フィールドの指定]
という形式で書きます。
「フィールドの指定」部分には一つか複数のフィールドから成る配列が入ります。
'unique keys' => [
'vid' => ['vid']
],
foreign keys
外部キーを定義する連想配列。
'[リレーション名]' => [リレーションの指定]
という形式で書きます。
「リレーションの指定」部分には参照先のテーブル('table'
)とフィールドのマッピング情報('column'
)が入ります。
フィールドのマッピング情報は'[ソースとなるフィールド]' => '[参照先のフィールド]'
という形式で書きます。
外部キーはデータベースでは作られず、Drupalで強制されているわけでもありません。
'foreign keys' => [
'affected_node' => [
'table' => 'node',
'columns' => ['nid' => 'nid'],
],
],
indexes
インデックスを定義する連想配列。
'[インデックス名]' => [インデックスの指定]
という形式で書きます。
「インデックスの指定」部分には一つ以上のキーとなるフィールドを指定します。
'indexes' => [
'module' => ['module'],
'name' => ['name'],
],
ノードモジュールのhook_schema
最後に、ノードモジュールのhook_schema
を転載しておきますのでご参考にしていただければと思います。
**
* Implements hook_schema().
*/
function node_schema() {
$schema['node_access'] = [
'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.',
'fields' => [
'nid' => [
'description' => 'The {node}.nid this record affects.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
'langcode' => [
'description' => 'The {language}.langcode of this node.',
'type' => 'varchar_ascii',
'length' => 12,
'not null' => TRUE,
'default' => '',
],
'fallback' => [
'description' => 'Boolean indicating whether this record should be used as a fallback if a language condition is not provided.',
'type' =>'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 1,
'size' => 'tiny',
],
'gid' => [
'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.",
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
],
'realm' => [
'description' => 'The realm in which the user must possess the grant ID. Modules can define one or more realms by implementing hook_node_grants().',
'type' => 'varchar_ascii',
'length' => 255,
'not null' => TRUE,
'default' => '',
],
'grant_view' => [
'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
],
'grant_update' => [
'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
],
'grant_delete' => [
'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
],
],
'primary key' => ['nid', 'gid', 'realm', 'langcode'],
'foreign keys' => [
'affected_node' => [
'table' => 'node',
'columns' => ['nid' => 'nid'],
],
],
];
return $schema;
}
募集しています
スタジオ・ウミは「Drupal」に特化したサービスを提供する Drupal のエキスパートチーム。
フルリモート&フレックス制だから、働く場所を選ばず時間の使い方も自由です。
そんなワークライフバランスの整った環境で、当ブログに書かれているような
様々な技術を共に学びながら、Drupalサイト開発に携わってみたい方を募集しています。
まずはお話だけでも大歓迎!ぜひお気軽にご連絡ください。