主キー
日本語 | 主鍵 |
英語 | primary key |
ふりがな | しゅきー |
フリガナ | シュキー |
テーブルの列に含まれる値が絶対に「複数存在しない」という列。
「プライマリキー」「一意制約」「PK」とも言う。
「プライマリキー」の「プライマリ」を「主」と訳したもの。
データベース用語。
列に設定する「制約」の一種。
主キーとした列は、絶対に値が重複しない。つまり、値が「一意」となる。
同じ値でINSERTしようとすると「一意制約違反」というエラーが発生する。
そのため、その列に含まれる値で検索すれば、必ず1行だけ取得できる。
通常、「絶対に重複しないID」等に用いられる。
プログラム上では、1行しか返らないのか複数行の可能性があるのか、によってプログラムが大きく異なる。主キーによって「1行しか返らない」ことが確実であれば、2行以上返された場合のエラー処理等を省くことができる。
また、主キーを設定することで、他のSQL実行アプリケーション等によって「誤って複数行追加してしまう」といったことを防ぐことができる。
制約の一種のため面倒な面もあり、「気を付ければ必要のない」ものではあるが、システムを堅牢にするためにも積極的に使用した方がいいだろう。
「プライマリキー」「一意制約」「PK」とも言う。
「プライマリキー」の「プライマリ」を「主」と訳したもの。
データベース用語。
列に設定する「制約」の一種。
主キーとした列は、絶対に値が重複しない。つまり、値が「一意」となる。
同じ値でINSERTしようとすると「一意制約違反」というエラーが発生する。
そのため、その列に含まれる値で検索すれば、必ず1行だけ取得できる。
通常、「絶対に重複しないID」等に用いられる。
プログラム上では、1行しか返らないのか複数行の可能性があるのか、によってプログラムが大きく異なる。主キーによって「1行しか返らない」ことが確実であれば、2行以上返された場合のエラー処理等を省くことができる。
また、主キーを設定することで、他のSQL実行アプリケーション等によって「誤って複数行追加してしまう」といったことを防ぐことができる。
制約の一種のため面倒な面もあり、「気を付ければ必要のない」ものではあるが、システムを堅牢にするためにも積極的に使用した方がいいだろう。
参考サイト
// Sample.java
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Sample
{
public static void main( String[] args )
{
Connection conn = null;
PreparedStatement psCreate = null;
PreparedStatement psInsert = null;
Statement stmt = null;
ResultSet resultSet = null;
try
{
// この使用例の使用方法についてはSQLの項目を参照してください。
// まずJDBCドライバを読み込みます。
Class.forName( "org.hsqldb.jdbcDriver" );
// JDBCに接続してコネクションを取得します。
String url = "jdbc:hsqldb:mem:aname";
String user = "sa";
String password = "";
conn = DriverManager.getConnection( url, user, password );
// テスト用テーブルを作ります。
// ID列を主キーにします。
psCreate = null;
final String SQL_CREATE
= "CREATE TABLE TABLE_TEST "
+ "( ID INT "
+ ", NAME VARCHAR "
+ ", PRIMARY KEY( ID ) " // これが主キーの設定です。
+ ");"
;
psCreate = conn.prepareStatement( SQL_CREATE );
psCreate.execute();
// そのテーブルに1行INSERTします。
final String SQL_INSERT = "INSERT INTO TABLE_TEST VALUES( ?, ? );";
psInsert = conn.prepareStatement( SQL_INSERT );
psInsert.setInt( 1, 100 );
psInsert.setString( 2, "名前1" );
psInsert.execute();
// もう一回、ID列を同じ値にしてINSERTします。
psInsert.setString( 2, "名前2" );
try
{
psInsert.execute();
}
catch( SQLException e )
{
// 例外が投げられました。
e.printStackTrace();
// java.sql.SQLException: Unique constraint violation: in statement [INSERT INTO TABLE_TEST VALUES( ?, ? );]
// at org.hsqldb.jdbc.Util.throwError(Unknown Source)
// at org.hsqldb.jdbc.jdbcPreparedStatement.execute(Unknown Source)
// at Sample.main(Sample.java:52)
// これが「一意制約違反」のエラーです。
// 注:エラーメッセージはデータベースによって異なるため注意。
}
// ID列が違う値ならINSERTできます。
psInsert.setInt( 1, 200 );
psInsert.setString( 2, "名前2" );
psInsert.execute();
// INSERTしたデータをSELECTでクエリーします。
stmt = conn.createStatement();
final String SQL_SELECT = "SELECT ID, NAME FROM TABLE_TEST WHERE ID = 100;";
resultSet = stmt.executeQuery( SQL_SELECT );
while( resultSet.next() )
{
int id = resultSet.getInt( "ID" );
String name = resultSet.getString( "NAME" );
System.out.println( id + ", " + name );
}
// 100, 名前1
// このように、1行取得できました。
}
catch( SQLException e )
{
// SQLの実行で問題があった場合に投げられます。
e.printStackTrace();
}
catch( ClassNotFoundException e )
{
// JDBCドライバが存在しなかった場合に投げられます。
e.printStackTrace();
}
finally
{
if( resultSet != null )
{
try
{
resultSet.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( stmt != null )
{
try
{
stmt.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psInsert != null )
{
try
{
psInsert.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psCreate != null )
{
try
{
psCreate.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( conn != null )
{
try
{
conn.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
}
}
}
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Sample
{
public static void main( String[] args )
{
Connection conn = null;
PreparedStatement psCreate = null;
PreparedStatement psInsert = null;
Statement stmt = null;
ResultSet resultSet = null;
try
{
// この使用例の使用方法についてはSQLの項目を参照してください。
// まずJDBCドライバを読み込みます。
Class.forName( "org.hsqldb.jdbcDriver" );
// JDBCに接続してコネクションを取得します。
String url = "jdbc:hsqldb:mem:aname";
String user = "sa";
String password = "";
conn = DriverManager.getConnection( url, user, password );
// テスト用テーブルを作ります。
// ID列を主キーにします。
psCreate = null;
final String SQL_CREATE
= "CREATE TABLE TABLE_TEST "
+ "( ID INT "
+ ", NAME VARCHAR "
+ ", PRIMARY KEY( ID ) " // これが主キーの設定です。
+ ");"
;
psCreate = conn.prepareStatement( SQL_CREATE );
psCreate.execute();
// そのテーブルに1行INSERTします。
final String SQL_INSERT = "INSERT INTO TABLE_TEST VALUES( ?, ? );";
psInsert = conn.prepareStatement( SQL_INSERT );
psInsert.setInt( 1, 100 );
psInsert.setString( 2, "名前1" );
psInsert.execute();
// もう一回、ID列を同じ値にしてINSERTします。
psInsert.setString( 2, "名前2" );
try
{
psInsert.execute();
}
catch( SQLException e )
{
// 例外が投げられました。
e.printStackTrace();
// java.sql.SQLException: Unique constraint violation: in statement [INSERT INTO TABLE_TEST VALUES( ?, ? );]
// at org.hsqldb.jdbc.Util.throwError(Unknown Source)
// at org.hsqldb.jdbc.jdbcPreparedStatement.execute(Unknown Source)
// at Sample.main(Sample.java:52)
// これが「一意制約違反」のエラーです。
// 注:エラーメッセージはデータベースによって異なるため注意。
}
// ID列が違う値ならINSERTできます。
psInsert.setInt( 1, 200 );
psInsert.setString( 2, "名前2" );
psInsert.execute();
// INSERTしたデータをSELECTでクエリーします。
stmt = conn.createStatement();
final String SQL_SELECT = "SELECT ID, NAME FROM TABLE_TEST WHERE ID = 100;";
resultSet = stmt.executeQuery( SQL_SELECT );
while( resultSet.next() )
{
int id = resultSet.getInt( "ID" );
String name = resultSet.getString( "NAME" );
System.out.println( id + ", " + name );
}
// 100, 名前1
// このように、1行取得できました。
}
catch( SQLException e )
{
// SQLの実行で問題があった場合に投げられます。
e.printStackTrace();
}
catch( ClassNotFoundException e )
{
// JDBCドライバが存在しなかった場合に投げられます。
e.printStackTrace();
}
finally
{
if( resultSet != null )
{
try
{
resultSet.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( stmt != null )
{
try
{
stmt.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psInsert != null )
{
try
{
psInsert.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( psCreate != null )
{
try
{
psCreate.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
if( conn != null )
{
try
{
conn.close();
}
catch( SQLException e )
{
// 各close()メソッドからもSQLException例外が
// 投げられるので、拾っておきます。
e.printStackTrace();
}
}
}
}
}
// Sample.java import java.sql.DriverManager; import java.sql.Connection; import java.sql.Statement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class Sample { public static void main( String[] args ) { Connection conn = null; PreparedStatement psCreate = null; PreparedStatement psInsert = null; Statement stmt = null; ResultSet resultSet = null; try { // この使用例の使用方法についてはSQLの項目を参照してください。 // まずJDBCドライバを読み込みます。 Class.forName( "org.hsqldb.jdbcDriver" ); // JDBCに接続してコネクションを取得します。 String url = "jdbc:hsqldb:mem:aname"; String user = "sa"; String password = ""; conn = DriverManager.getConnection( url, user, password ); // テスト用テーブルを作ります。 // ID列を主キーにします。 psCreate = null; final String SQL_CREATE = "CREATE TABLE TABLE_TEST " + "( ID INT " + ", NAME VARCHAR " + ", PRIMARY KEY( ID ) " // これが主キーの設定です。 + ");" ; psCreate = conn.prepareStatement( SQL_CREATE ); psCreate.execute(); // そのテーブルに1行INSERTします。 final String SQL_INSERT = "INSERT INTO TABLE_TEST VALUES( ?, ? );"; psInsert = conn.prepareStatement( SQL_INSERT ); psInsert.setInt( 1, 100 ); psInsert.setString( 2, "名前1" ); psInsert.execute(); // もう一回、ID列を同じ値にしてINSERTします。 psInsert.setString( 2, "名前2" ); try { psInsert.execute(); } catch( SQLException e ) { // 例外が投げられました。 e.printStackTrace(); // java.sql.SQLException: Unique constraint violation: in statement [INSERT INTO TABLE_TEST VALUES( ?, ? );] // at org.hsqldb.jdbc.Util.throwError(Unknown Source) // at org.hsqldb.jdbc.jdbcPreparedStatement.execute(Unknown Source) // at Sample.main(Sample.java:52) // これが「一意制約違反」のエラーです。 // 注:エラーメッセージはデータベースによって異なるため注意。 } // ID列が違う値ならINSERTできます。 psInsert.setInt( 1, 200 ); psInsert.setString( 2, "名前2" ); psInsert.execute(); // INSERTしたデータをSELECTでクエリーします。 stmt = conn.createStatement(); final String SQL_SELECT = "SELECT ID, NAME FROM TABLE_TEST WHERE ID = 100;"; resultSet = stmt.executeQuery( SQL_SELECT ); while( resultSet.next() ) { int id = resultSet.getInt( "ID" ); String name = resultSet.getString( "NAME" ); System.out.println( id + ", " + name ); } // 100, 名前1 // このように、1行取得できました。 } catch( SQLException e ) { // SQLの実行で問題があった場合に投げられます。 e.printStackTrace(); } catch( ClassNotFoundException e ) { // JDBCドライバが存在しなかった場合に投げられます。 e.printStackTrace(); } finally { if( resultSet != null ) { try { resultSet.close(); } catch( SQLException e ) { // 各close()メソッドからもSQLException例外が // 投げられるので、拾っておきます。 e.printStackTrace(); } } if( stmt != null ) { try { stmt.close(); } catch( SQLException e ) { // 各close()メソッドからもSQLException例外が // 投げられるので、拾っておきます。 e.printStackTrace(); } } if( psInsert != null ) { try { psInsert.close(); } catch( SQLException e ) { // 各close()メソッドからもSQLException例外が // 投げられるので、拾っておきます。 e.printStackTrace(); } } if( psCreate != null ) { try { psCreate.close(); } catch( SQLException e ) { // 各close()メソッドからもSQLException例外が // 投げられるので、拾っておきます。 e.printStackTrace(); } } if( conn != null ) { try { conn.close(); } catch( SQLException e ) { // 各close()メソッドからもSQLException例外が // 投げられるので、拾っておきます。 e.printStackTrace(); } } } } }