データベースの整合性とは、データベースの正確性と互換性を指します。正確性とは、現実世界のセマンティクスに準拠し、現在の実際の状況を反映していることを意味します。データの互換性とは、異なるリレーショナルテーブルのデータベース内の同じオブジェクトのデータが論理的であることを意味します。データベースの整合性はデータベース内の誤ったデータを防ぐことであり、データベースのセキュリティは悪意のある破壊や不正な取得を防ぐことです。
データベースの整合性を維持するには、データベース管理システムが次の機能を実行できる必要があります。
- 整合性制約を定義するためのメカニズムを提供する
- 整合性チェック方法を提供する
- 契約違反を続行します
1.エンティティの整合性
エンティティの整合性を定義する
エンティティの整合性を定義するということは、テーブルの主キーを設定すること、つまり、テーブルを作成するときに主キーを定義することを意味します。
例
-- 第一种 列级定义
create table table_name(
id int primary key,
name varchar(10),
address varchar(50)
)
-- 第二种(可以定义多个) 表级定义
create table table_name(
id int,
name varchar(10),
primary key(id,name)
)
既存のテーブルに主キーを追加します
alter table_name add constraint pk_table_name primary key('field')
エンティティの整合性チェックとデフォルトの処理
primary key
フレーズとの関係のメインコードを定義した後、ユーザープログラムが基本テーブルに対応するデータ操作を挿入または変更するたびに、リレーショナルデータベースシステムはエンティティの整合性に従って次のチェックを実行します。
- メインコードが一意であるかどうかを確認し、一意でない場合は、挿入または変更を拒否します
- メインコードの各属性が空であるかどうかを確認し、1つが空である限り、挿入または変更を拒否します(SQLが空でない制約を定義しているように、この個人的な感覚は現在のデータベースとは異なり、空の場合は拒否します挿入または変更する)
マスターコードかどうかを確認する唯一の方法は、ディスク全体をスキャンして、各レコードのマスターコードを順番に確認することです。ただし、全表スキャンには非常に時間がかかります。全表スキャンを回避するために、リレーショナルデータベースシステムは通常、マスターコードにインデックス(B +ツリーインデックスなど)を自動的に作成します。これにより、マスターコードかどうかが大幅に向上します。インデックスを介してルックアップテーブルにすでに存在します。
2.参照整合性
参照整合性を定義する
参照整合性を定義することは、実際には外部キー制約をテーブルに追加することです。foreign key
フレーズを使用して、どのクラスが外部コードであるかを定義し、references
フレーズを使用して、これらの外部コードが参照するメインコード
例のテーブルを示します。
create table table course(
id int primary key,
name varchar(10)
)
create table stu(
id int not null,
name varchar(10),
cId int,
foreign key(cId) references course(id)
)
既存のテーブルに外部キーを追加します
create table table course(
id int primary key,
name varchar(10)
)
create table stu(
id int not null,
name varchar(10),
cId int
)
alter table stu add constraint stu_cId_fk_course_id foreign key(cId) references course(id)
参照整合性チェックと不正な処理
参照整合性は、2つのテーブルの対応するタプルをリンクします。したがって、参照テーブルと参照テーブルを追加、削除、または変更すると、参照整合性が失われる可能性があるため、2つのテーブルの互換性を確認するためにチェックを実行する必要があります。
上記の定義整合性の作成を例にとると(stuは参照テーブル、courseは参照テーブル)、参照整合性を破壊する可能性のある状況は4つあります。
- 学生が学生テーブル(stu)に追加されますが、学生が学習したコースはコーステーブルにありません。
- 学生テーブル(stu)のコースCidを変更しますが、コーステーブル(course)には対応するIDがありません
- コーステーブルのコースを削除して、学生テーブルのCidのIDがコーステーブルのCidと等しくならないようにします。
- 学生テーブルのCidがコーステーブルのIDと同じにならないように、コーステーブルのIDを変更します。
上記の状況が発生した場合、システムは以下の戦略を採用して対処することができます。
- 拒否(
NO ACTION
)実行:デフォルトの戦略 - カスケード(
CASCADE
)操作
参照テーブル(コース)のタプルを削除または変更すると、参照テーブル(stu)との不整合が発生する場合は、参照テーブル内の矛盾するタプルをすべて削除または変更します。 - null値に設定
参照テーブル(コース)のソースを削除するか、参照テーブル(stu)との不整合が発生する場合は、参照テーブル内のすべての不整合属性をnull値に設定します。
参照整合性のために、外部コードの定義に加えて、外部コードをnullにできるかどうかも定義する必要があります
3.ユーザー定義の完全性
ユーザー定義の整合性は、特定のアプリケーションのデータが満たさなければならないセマンティック要件です。
属性の制約
でcreate table
属性を定義するときに、要件に応じて属性の制約、つまり属性値の制限を定義できます。一般に、次のようなものがあります。
- 列の値がNULLではない(NULLではない)
- 列の値は一意です(一意)
- 列の値が特定の条件式を満たしているかどうかを確認します(フレーズを確認してください、mysqlはサポートしていません)
タプルの制約
属性の制約条件と同様に、create table
チェックフレーズは、タプルの制約条件を定義するために文で使用されます。
例:学生テーブルを定義します。学生が「男性」の場合、その名前を「Ms」で始めることはできません。
create table stu(
id int,
name varchar(20),
sex char(2),
check(sex='女' OR name not like 'Ms.%')
)
4.整合性制約の命名句
整合性命名句は、実際には、CONSTRAINT
整合性制約を定義するためのキーワードの使用です。
整合性命名条項
CONSTRAINT <完整性约束条件名> <完整性约束条件>
整合性制約にはNOT NULL
、UNIQUE
、PRIMARY KEY
、FOREIGN KEY
例:学生登録フォームstuを作成するには、学生IDが90000〜99999である必要があり、名前を空にすることはできず、年齢は40歳未満であり、性別は「男性」または「女性」のみです。
create table stu(
sno int constraint c1 check(sno between 90000 and 99999),
sname char(20) constraint c2 check not null,
sage int constraint c3 check(sage<40),
sex char(2) constraint c4 check(sex in("男","女")),
constraint pk_stu primary key(sno)
)
テーブルの整合性制限を変更します
表の整合性制限を変更するということは、制限を削除するか、制限を追加することを意味します。
制限を削除する
alter table stu drop constraint c4
制限を追加する
alter table add constraint c4 check(sex in("男","女"))
mysqlはチェック制約をサポートしていないことに注意してください、check
制約を使用する場合は、Sqlserverまたはその他のリレーショナルデータベースを使用してください。
5.ドメイン内の整合性の制限
通常、ドメインは同じデータ型のコレクションのグループです。SQLはドメインの概念をサポートしています。CREATE DOMAIN
ステートメントを使用して、ドメインと、ドメインが満たす整合性制約を確立できます。
ドメインを作成し、ドメインの値の範囲を宣言します。
CREATE DOMAIN generderDomain char(2) constraint gd check(value in ("男","女"))
テーブルを作成するときは、上記で作成したドメインを使用してください。
create table stu(
id int,
name varchar(10),
sex generderDomain
)
6.断言
InSQL
は、データベース定義言語CREATE ASSERTION
ステートメントを使用して、宣言型制約によってより一般的なアサーションを指定できます。簡単に言えば、操作を実行する前のチェックと判断であり、結果が真の場合は実行でき、結果が偽の場合は実行を拒否します。
アサーションを作成する
create ASSERTION <断言名> <check 子句>
例。データベースコースを選択科目として60人の学生に制限します
create ASSERTION ASSE_SC_DB_NUM
CHECK(60>=(select count(*) from Course,Sc where Sc.no = course.cno and course.cname = '数据库'))
ここではSc
学生やコース選択、との関係の表であるCourse
もちろんテーブル、およびno
学生のIDは
アサーションを削除する
DROP ASSERTION <断言名>
アサーションが非常に複雑な場合、システムはアサーションの検出と維持にかかるオーバーヘッドが高くなります。これは、アサーションの使用時に注意を払う必要があります(mysqlは当面アサーションをサポートしません)。
7.トリガー
トリガーは、リレーショナルテーブルでユーザーが定義する特別なイベント駆動型プロセスです。定義すると、トリガーはデータベースサーバーに保存されます。サーバーは、ユーザーの追加、削除、および変更操作に対応するトリガーを自動的にアクティブ化し、リレーショナルデータベースシステムのコアレイヤーで一元化された整合性制御が実行されます。トリガーは制約に似ていますが、制約よりも柔軟性があり、より複雑なチェックと操作を実装できます。
トリガーはSQL99の後にSQL標準に書き込まれましたが、多くのリレーショナルデータベースはずっと前にトリガーをサポートしていたので、リレーショナルデータベースが異なれば、トリガーの文法も異なり、補完的で互換性があります。。
トリガーを定義する
トリガーは、イベント条件アクションルールとも呼ばれます。特定のシステムイベントが発生すると、ルールの条件がチェックされ、条件が満たさ
れている場合はルール内のアクションが実行され、そうでない場合はアクションは実行されません。
文法:
CREATE TRIGGER <触发器名>
{BEFORE | AFTER} <触发事件> ON <表名> --指明触发器激活事件是执行触发事件的前或后
REFERENCING NEW|OLD ROW AS<变量> -- REFERENCING 指出引用的变量
FOR EACH {ROW | STATEMENT} -- 定义触发器的类型,指明动作执行的频率
[WHEN <触发条件>]<触发动作体>
文法の説明
- テーブルの所有者、つまりテーブルを作成したユーザーのみがトリガーを作成でき、テーブルは特定の数の発行者のみを作成できます。
- トリガー名
トリガー名には、パターン名を含めることも含めないこともできます。同じモードでは、トリガー名は一意である必要があり、トリガー名とテーブル名は同じモードである必要があります。 - テーブル名
トリガーは、ビューではなく、ベーステーブルでのみ定義できます。基本テーブルのデータが変更されると、テーブルに定義されている対応するトリガーがアクティブ化されるため、そのテーブルはトリガーのターゲットテーブルとも呼ばれます。 - トリガ・イベントの
イベントをトリガーにすることができるINSET
、、DELETE
、UPDATE
それはこれらの事象の組み合わせであってもよいです。UPDATE OF <trigger column、…>にすることもできます。つまり、トリガーをアクティブにするためにどの列を変更するかをさらに指定します。BEFORE | AFTER
これはトリガーのタイミングです。AFTER
つまり、イベントをトリガーする操作が実行された後にアクティベーターがトリガーされ、BEFORE
トリガーイベントが実行される前にトリガーがアクティブになります。 - トリガーの種類
トリガーは、トリガーされたアクションの間隔サイズに応じて、行レベルのトリガー(FOR EACH ROW)とステートメントレベルのトリガー(FOR EACH STATEMENT)に分けることができます。
例:TEACHERテーブルにAFTER UPDATEトリガーを作成します。トリガーイベントはUPDATEステートメントです
。UPDATETEACHERSETDeptno = 5;
テーブルTEACHERに1000行あると仮定します。
ステートメントレベルのトリガーの場合、ステートメントの後は次のようになります。実行されると、トリガーアクションは1回だけ発生します。
行レベルのトリガーの場合、トリガーアクションは1000回実行されます。
- トリガー条件
トリガーがアクティブ化されると、トリガーアクション本体はトリガー条件がtrueの場合にのみ実行され、それ以外の場合は実行されません。省略したwhen
場合、トリガーがアクティブになるとすぐにトリガー本体が実行されます。 - トリガーアクション本体
トリガーアクション本体は、匿名のPL/SQL
プロセスブロック、または作成されたストアドプロシージャの呼び出しのいずれかです。行レベルのトリガーの場合、ユーザーはイベント後の新しい値とイベント前の古い値をプロシージャ本体で使用NEW
およびOLD
参照できます。ステートメントレベルのトリガーの場合、で使用NEW
またはOLD
参照することはできません。アクション本体のトリガー;トリガーされた場合アクション本体の実行が失敗した場合、トリガーをアクティブ化したイベントは実行を終了し、トリガーのターゲットテーブルまたはトリガーが影響を与える可能性のあるその他のオブジェクトは変更されません。
例1.テーブルSCのGrade属性を変更するときに、スコアが10%増加した場合は、この操作を次のテーブルに記録します
。SC_U(Sno、Cno、Oldgrade、Newgrade)
ここで、Oldgradeは変更前のスコア、Newgradeは変更されますスコア。
CREATE TRIGGER SC_T --创建触发器,触发器名SC_T
AFTER UPDATE OF Grade ON SC -- 触发事件的操作执行之后激活触发器,即表SC的grade属性修改后再触发下面的规则
REFERENCING --新值和旧值
OLD row AS OldTuple,
NEW row AS NewTuple
FOR EACH ROW -- 触发器类型为行级触发器
WHEN (NewTuple.Grade >= 1.1*OldTuple.Grade) -- 触发条件
INSERT INTO SC_U(Sno,Cno,OldGrade,NewGrade) --触发动作体插入操作
VALUES(OldTuple.Sno,OldTuple.Cno,OldTuple.Grade,NewTuple.Grade)
行レベルのトリガー(FOR EACH ROW)は、OLDおよびNEWを使用して、新しい値と古い値を参照できます。、行レベルのトリガーでない場合は、を使用NEWTABLE
しOLDTABLE
て元のコンテンツと新しいコンテンツを表すことができます。
次の2つの例がmysqlに適用されます。
実行ステートメントが1つだけのトリガーを作成する
CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件 ON 表名 FOR EACH ROW 执行语句;
たとえば、trig1という名前のトリガーが作成されます。作業テーブルに挿入アクションがあると、現在の時刻がタイムテーブルに自動的に挿入されます。
CREATE TRIGGER trig1 AFTER INSERT
ON work FOR EACH ROW
INSERT INTO time VALUES(NOW());
複数の実行ステートメントでトリガーを作成する
CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件
ON 表名 FOR EACH ROW
BEGIN
执行语句列表
END;
例、トリガーを定義します。条件を満たす削除操作があると、BEGINとENDのステートメントが実行されます。
CREATE TRIGGER trig2 BEFORE DELETE
ON work FOR EACH ROW
BEGIN
INSERT INTO time VALUES(NOW());
INSERT INTO time VALUES(NOW());
END
アクティベーショントリガー
トリガーの実行は、トリガーイベントによってアクティブ化され、データベースサーバーによって自動的に実行されます。データテーブルには1つ以上のトリガーが存在する場合があります。トリガーがアクティブ化されると、次の実行シーケンスに従います。
- テーブルで
BEFORE
トリガーを実行します - トリガー
SQL
をアクティブにするステートメント - テーブルで
AFTER
トリガーを実行します。
一般的に、テーブルに複数のBEFORE
トリガーがある場合、実行順序ルールは「誰が最初に作成し、誰が最初に実行するか」です。ただし、一部のリレーショナルデータベースは、トリガー名のアルファベット順にトリガーを実行します。
トリガーの削除
構文は次のとおりです。
DROP TRIGGER <触发器名> ON <表名>
トリガーは作成済みのトリガーである必要があり、対応する権限を持つユーザーのみが削除できます。