#import "@preview/mitex:0.2.5": mitex
#let bem-md-hash = "37961fd"
#let bem-page-path = "book:ja"
#set page(paper: "a4", margin: (x: 18mm, y: 18mm), foreground: place(top + left, dx: 8mm, dy: 7mm)[#text(size: 7pt, fill: luma(120))[#bem-page-path]], footer: context align(right)[#text(size: 7pt, fill: luma(120))[md #bem-md-hash #h(1em)p. #counter(page).display("1")]])
#let bem-ruby-color = luma(120)
#let bem-ruby-reserve = 0.45em
#let bem-anno-reserve = 0.45em
#let bem-anno-gap = bem-anno-reserve
#let bem-anno-area = bem-anno-reserve + bem-anno-gap
#set text(font: ("Yu Mincho", "MS Mincho"), size: 10.5pt, lang: "ja", fill: black, top-edge: 1em + bem-ruby-reserve, bottom-edge: -bem-anno-area)
#set par(justify: true, leading: 0.18em)
#set block(spacing: 1.12em)
#set heading(numbering: "1.1.1")
#let bem-heading-accent = rgb("2b155f")
#let bem-heading-line = rgb("58b7ff")
#let bem-ruby(rt, body) = context {
  let rt-body = text(size: bem-ruby-reserve, fill: bem-ruby-color, top-edge: "bounds", bottom-edge: "bounds")[#rt]
  let bw = measure(body).width
  let rw = measure(rt-body).width
  let w = calc.max(bw, rw)
  box(width: w, baseline: bem-anno-area)[
    #align(center)[#body]
    #place(top + left, dx: (w - rw) / 2, rt-body)
  ]
}
#let bem-anno(note, body) = context {
  let note-body = text(size: bem-anno-reserve, fill: bem-ruby-color, top-edge: "bounds", bottom-edge: "bounds")[#note]
  let bw = measure(body).width
  let nw = measure(note-body).width
  let w = calc.max(bw, nw)
  box(width: w, baseline: bem-anno-area)[
    #align(center)[#body]
    #place(bottom + left, dx: (w - nw) / 2, note-body)
  ]
}
#let bem-heading-number() = {
  let nums = counter(heading).get().slice(1)
  if nums.len() == 0 { [] } else { numbering("1.1.1", ..nums) }
}
#show heading: it => {
  if it.level == 1 {
    block(above: 0.35em, below: 1.85em, width: 100%)[
      #align(center)[#text(size: 18pt, weight: 700)[#it.body]]
    ]
  } else {
    let shown = bem-heading-number()
    let size = if it.level == 2 { 13.2pt } else if it.level == 3 { 11.6pt } else { 10.8pt }
    let above = if it.level == 2 { 1.4em } else { 1.12em }
    let below = if it.level == 2 { 1.22em } else { 1.02em }
    block(above: above, below: below, width: 100%)[
      #box(width: 100%, inset: (left: 7pt, right: 6pt, top: 9pt, bottom: 12pt), stroke: (left: 2.4pt + bem-heading-accent, bottom: 0.55pt + bem-heading-line), radius: 1.5pt)[
        #text(size: size, weight: 700)[#if shown != [] [#shown #h(0.45em)]#it.body]
      ]
    ]
  }
}
#set document(title: "データベースポータル")

#align(center + horizon)[
#block(width: 82%)[
#text(size: 24pt, weight: 700)[データベースポータル]

#text(size: 8pt, fill: luma(120))[3 pages]
]
]

#pagebreak()

#block(above: 0pt, below: 0.55em)[#text(size: 14pt, weight: 700)[Table of Contents]]
#outline(title: none, depth: 3)

#pagebreak()


#block(above: 0.1em, below: 0.45em, width: 100%)[#text(size: 7pt, fill: luma(125))[data/lecture/information/database/database-portal.lecture.n.md#h(0.7em)md e8f09b0]]


= データベースポータル


#block(above: 1.35em, below: 1.0em, width: 100%)[
#link("https://study.bem130.com/lecture/information/networks/http-basics.lecture/")[#box(width: 100%, inset: (x: 7pt, y: 5pt), stroke: 0.55pt + rgb("d8dee8"), radius: 3pt, fill: rgb("fbfcfe"))[
#set par(justify: false, leading: 0.35em)
#text(size: 7pt, fill: rgb("5d7796"))[→]#h(0.32em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("f4f6f9"), stroke: 0.45pt + rgb("d7dde6"))[#text(size: 6.8pt, fill: rgb("54657a"))[basics.lecture]]#h(0.32em)#text(size: 9.2pt, weight: 700, fill: rgb("182232"))[http]#h(0.5em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[lecture]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[information]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[networks]]#h(0.24em) \
#text(size: 7pt, fill: rgb("5d7796"))[https://study.bem130.com/lecture/information/networks/http-basics.lecture/]
]]
]


== #bem-ruby("どうにゅう")[導入]


このポータルでは、データを#bem-ruby("えいぞくてき")[永続的]に#bem-ruby("ほぞん")[保存]し、#bem-ruby("せいごうせい")[整合性]を#bem-ruby("いじ")[維持]しながら#bem-ruby("けんさく")[検索]・#bem-ruby("こうしん")[更新]するためのデータベース#bem-ruby("ぎじゅつ")[技術]を#bem-ruby("まな")[学]ぶ。#bem-ruby("せんこう")[先行]するネットワーク#bem-ruby("けいれつ")[系列]では、HTTP によってクライアントとサーバが#bem-ruby("ようきゅう")[要求]と#bem-ruby("おうとう")[応答]を#bem-ruby("こうかん")[交換]する#bem-ruby("しく")[仕組]みを#bem-ruby("せつめい")[説明]した。サーバが#bem-ruby("ふくすう")[複数]の#bem-ruby("ようきゅう")[要求]にわたってデータを#bem-ruby("ほじ")[保持]するには、#bem-ruby("つうしん")[通信]とは#bem-ruby("べつ")[別]にデータの#bem-ruby("かんり")[管理]を#bem-ruby("こうさつ")[考察]する#bem-ruby("ひつよう")[必要]がある。


== #bem-ruby("がくしゅうけいろ")[学習経路]


+ データベースとデータベース#bem-ruby("かんり")[管理]システムの#bem-ruby("やくわり")[役割]を#bem-ruby("くべつ")[区別]する。

+ #bem-ruby("かんけい")[関係]モデルにおける#bem-ruby("かんけい")[関係]スキーマ、タプル、#bem-ruby("ぞくせい")[属性]、ドメインを#bem-ruby("りかい")[理解]する。

+ キーと#bem-ruby("せいごうせいせいやく")[整合性制約]によってデータの#bem-ruby("いっかんせい")[一貫性]を#bem-ruby("ひょうげん")[表現]する。

+ SQL によって#bem-ruby("けんさく")[検索]・#bem-ruby("ついか")[追加]・#bem-ruby("こうしん")[更新]・#bem-ruby("さくじょ")[削除]を#bem-ruby("せんげんてき")[宣言的]に#bem-ruby("きじゅつ")[記述]する。


#block(above: 1.35em, below: 1.0em, width: 100%)[
#link("https://study.bem130.com/lecture/information/database/database-basics.lecture/")[#box(width: 100%, inset: (x: 7pt, y: 5pt), stroke: 0.55pt + rgb("d8dee8"), radius: 3pt, fill: rgb("fbfcfe"))[
#set par(justify: false, leading: 0.35em)
#text(size: 7pt, fill: rgb("5d7796"))[→]#h(0.32em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("f4f6f9"), stroke: 0.45pt + rgb("d7dde6"))[#text(size: 6.8pt, fill: rgb("54657a"))[basics.lecture]]#h(0.32em)#text(size: 9.2pt, weight: 700, fill: rgb("182232"))[データベースの基本]#h(0.5em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[lecture]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[information]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[database]]#h(0.24em) \
#text(size: 7pt, fill: rgb("5d7796"))[https://study.bem130.com/lecture/information/database/database-basics.lecture/]
]]
]


#block(above: 1.35em, below: 1.0em, width: 100%)[
#link("https://study.bem130.com/lecture/information/database/sql-basics.lecture/")[#box(width: 100%, inset: (x: 7pt, y: 5pt), stroke: 0.55pt + rgb("d8dee8"), radius: 3pt, fill: rgb("fbfcfe"))[
#set par(justify: false, leading: 0.35em)
#text(size: 7pt, fill: rgb("5d7796"))[→]#h(0.32em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("f4f6f9"), stroke: 0.45pt + rgb("d7dde6"))[#text(size: 6.8pt, fill: rgb("54657a"))[basics.lecture]]#h(0.32em)#text(size: 9.2pt, weight: 700, fill: rgb("182232"))[SQL の基本]#h(0.5em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[lecture]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[information]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[database]]#h(0.24em) \
#text(size: 7pt, fill: rgb("5d7796"))[https://study.bem130.com/lecture/information/database/sql-basics.lecture/]
]]
]


== #bem-ruby("かんりたいしょう")[管理対象]と#bem-ruby("そうさ")[操作]を#bem-ruby("くべつ")[区別]する


データベースは#bem-ruby("そしきか")[組織化]されたデータの#bem-ruby("しゅうごう")[集合]であり、データベース#bem-ruby("かんり")[管理]システムはその#bem-ruby("ていぎ")[定義]、#bem-ruby("ほぞん")[保存]、#bem-ruby("けんさく")[検索]、#bem-ruby("こうしん")[更新]、#bem-ruby("ほご")[保護]を#bem-ruby("にな")[担]うソフトウェアである。#bem-ruby("かんけい")[関係]モデルはデータと#bem-ruby("せいやく")[制約]を#bem-ruby("きじゅつ")[記述]するための#bem-ruby("わくぐ")[枠組]みを#bem-ruby("ていきょう")[提供]し、SQL はその#bem-ruby("わくぐ")[枠組]みに#bem-ruby("もと")[基]づくデータベースへ#bem-ruby("といあわ")[問合]せや#bem-ruby("こうしん")[更新]を#bem-ruby("きじゅつ")[記述]する#bem-ruby("げんご")[言語]である。これらの#bem-ruby("やくわり")[役割]を#bem-ruby("くべつ")[区別]すると、データの#bem-ruby("こうぞう")[構造]、#bem-ruby("せいりつ")[成立]すべき#bem-ruby("せいやく")[制約]、#bem-ruby("じっこう")[実行]する#bem-ruby("そうさ")[操作]を#bem-ruby("たいけいてき")[体系的]に#bem-ruby("ぶんせき")[分析]できる。


#pagebreak()


#block(above: 0.1em, below: 0.45em, width: 100%)[#text(size: 7pt, fill: luma(125))[data/lecture/information/database/database-basics.lecture.n.md#h(0.7em)md 32d7237]]


= データベースの#bem-ruby("きほん")[基本]


#block(above: 1.35em, below: 1.0em, width: 100%)[
#link("https://study.bem130.com/lecture/information/database/database-portal.lecture/")[#box(width: 100%, inset: (x: 7pt, y: 5pt), stroke: 0.55pt + rgb("d8dee8"), radius: 3pt, fill: rgb("fbfcfe"))[
#set par(justify: false, leading: 0.35em)
#text(size: 7pt, fill: rgb("5d7796"))[→]#h(0.32em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("f4f6f9"), stroke: 0.45pt + rgb("d7dde6"))[#text(size: 6.8pt, fill: rgb("54657a"))[portal.lecture]]#h(0.32em)#text(size: 9.2pt, weight: 700, fill: rgb("182232"))[データベースポータル]#h(0.5em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[lecture]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[information]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[database]]#h(0.24em) \
#text(size: 7pt, fill: rgb("5d7796"))[https://study.bem130.com/lecture/information/database/database-portal.lecture/]
]]
]


== #bem-ruby("どうにゅう")[導入]


この#bem-ruby("こうぎ")[講義]では、データベース#bem-ruby("かんり")[管理]システムによってデータを#bem-ruby("えいぞくてき")[永続的]かつ#bem-ruby("いっかん")[一貫]して#bem-ruby("かんり")[管理]するための#bem-ruby("きほんがいねん")[基本概念]を#bem-ruby("せつめい")[説明]する。#bem-ruby("とく")[特]に、#bem-ruby("かんけい")[関係]モデルの#bem-ruby("こうせいようそ")[構成要素]、キーと#bem-ruby("せいごうせいせいやく")[整合性制約]、#bem-ruby("せいきか")[正規化]の#bem-ruby("もくてき")[目的]、トランザクションの ACID #bem-ruby("とくせい")[特性]を#bem-ruby("どうにゅう")[導入]する。


HTTP サーバは#bem-ruby("ようきゅう")[要求]を#bem-ruby("しょり")[処理]し、#bem-ruby("ひつよう")[必要]に#bem-ruby("おう")[応]じて#bem-ruby("ひょうげん")[表現]を#bem-ruby("せいせい")[生成]するが、#bem-ruby("りようしゃ")[利用者]、#bem-ruby("しょうひん")[商品]、#bem-ruby("ちゅうもん")[注文]などのデータは#bem-ruby("ここ")[個々]の#bem-ruby("つうしん")[通信]が#bem-ruby("しゅうりょう")[終了]した#bem-ruby("あと")[後]にも#bem-ruby("ほじ")[保持]される。このようなデータを#bem-ruby("ふくすう")[複数]のプログラムや#bem-ruby("りようしゃ")[利用者]から#bem-ruby("あんぜん")[安全]に#bem-ruby("きょうゆう")[共有]するには、#bem-ruby("ほぞんけいしき")[保存形式]だけでなく、#bem-ruby("せいやく")[制約]、#bem-ruby("どうじじっこう")[同時実行]、#bem-ruby("しょうがい")[障害]からの#bem-ruby("かいふく")[回復]を#bem-ruby("かんり")[管理]する#bem-ruby("しく")[仕組]みが#bem-ruby("ひつよう")[必要]である。


== データベースと DBMS


#bem-anno("Database")[データベース]とは、#bem-ruby("とくてい")[特定]の#bem-ruby("もくてき")[目的]に#bem-ruby("したが")[従]って#bem-ruby("そしきか")[組織化]され、#bem-ruby("えいぞくてき")[永続的]に#bem-ruby("かんり")[管理]されるデータの#bem-ruby("しゅうごう")[集合]である。


#bem-anno("Database management system; DBMS")[データベース#bem-ruby("かんり")[管理]システム]とは、データベースの#bem-ruby("ていぎ")[定義]、#bem-ruby("ほぞん")[保存]、#bem-ruby("けんさく")[検索]、#bem-ruby("こうしん")[更新]、アクセス#bem-ruby("せいぎょ")[制御]、#bem-ruby("どうじじっこうせいぎょ")[同時実行制御]、#bem-ruby("しょうがいかいふく")[障害回復]などを#bem-ruby("ていきょう")[提供]するソフトウェアである。データベースが#bem-ruby("かんりたいしょう")[管理対象]となるデータであるのに#bem-ruby("たい")[対]し、DBMS はそのデータを#bem-ruby("かんり")[管理]する#bem-ruby("きこう")[機構]である。


== #bem-ruby("かんけい")[関係]モデルの#bem-ruby("こうせいようそ")[構成要素]


#bem-anno("Relational model")[#bem-ruby("かんけい")[関係]モデル]では、データを#bem-ruby("かんけい")[関係]として#bem-ruby("ひょうげん")[表現]する。#bem-ruby("じっそうじょう")[実装上]は#bem-ruby("ひょう")[表]として#bem-ruby("ひょうじ")[表示]されることが#bem-ruby("おお")[多]いが、#bem-ruby("かんけい")[関係]は#bem-ruby("たん")[単]なる#bem-ruby("ぎょうれつけいしき")[行列形式]のファイルではなく、#bem-ruby("ぞくせい")[属性]とタプルからなる#bem-ruby("すうがくてき")[数学的]な#bem-ruby("こうぞう")[構造]である。


- #bem-anno("Attribute")[#bem-ruby("ぞくせい")[属性]]は、データを#bem-ruby("とくちょう")[特徴]づける#bem-ruby("なまえ")[名前]の#bem-ruby("つ")[付]いた#bem-ruby("こうもく")[項目]である。

- #bem-anno("Domain")[ドメイン]は、ある#bem-ruby("ぞくせい")[属性]が#bem-ruby("と")[取]り#bem-ruby("う")[得]る#bem-ruby("あたい")[値]の#bem-ruby("しゅうごう")[集合]である。

- #bem-anno("Tuple")[タプル]は、#bem-ruby("かくぞくせい")[各属性]に#bem-ruby("たいおう")[対応]する#bem-ruby("あたい")[値]をまとめた#bem-ruby("いっけん")[一件]のデータである。

- #bem-anno("Relation schema")[#bem-ruby("かんけい")[関係]スキーマ]は、#bem-ruby("かんけいめい")[関係名]と#bem-ruby("ぞくせい")[属性]の#bem-ruby("こうせい")[構成]を#bem-ruby("さだ")[定]める。

- #bem-anno("Relation instance")[#bem-ruby("かんけい")[関係]インスタンス]は、ある#bem-ruby("じてん")[時点]でスキーマに#bem-ruby("てきごう")[適合]するタプルの#bem-ruby("しゅうごう")[集合]である。


たとえば、#bem-ruby("がくせい")[学生]を#bem-ruby("ひょうげん")[表現]する#bem-ruby("かんけい")[関係]スキーマを#bem-ruby("つぎ")[次]のように#bem-ruby("きじゅつ")[記述]できる。


#align(center)[#mitex("\\operatorname{Student}(\\mathit{student\\_id},\\ \\mathit{name},\\ \\mathit{department\\_id})")]


この#bem-ruby("ばあい")[場合]、#raw("student_id")、#raw("name")、#raw("department_id") が#bem-ruby("ぞくせい")[属性]であり、#bem-ruby("ここ")[個々]の#bem-ruby("がくせい")[学生]に#bem-ruby("たいおう")[対応]する#bem-ruby("あたい")[値]の#bem-ruby("くみ")[組]がタプルである。


== キー


#bem-anno("Superkey")[スーパーキー]とは、#bem-ruby("かんけい")[関係]スキーマで#bem-ruby("きょよう")[許容]されるすべてのインスタンスにおいて、#bem-ruby("かく")[各]タプルを#bem-ruby("いちい")[一意]に#bem-ruby("しきべつ")[識別]することが#bem-ruby("せいやく")[制約]された#bem-ruby("ぞくせいしゅうごう")[属性集合]である。#bem-anno("Candidate key")[#bem-ruby("こうほ")[候補]キー]とは、いずれの#bem-ruby("しんぶぶんしゅうごう")[真部分集合]もスーパーキーではない#bem-ruby("きょくしょう")[極小]なスーパーキーである。


#bem-anno("Primary key")[#bem-ruby("しゅ")[主]キー]とは、#bem-ruby("こうほ")[候補]キーのうち、タプルの#bem-ruby("しゅよう")[主要]な#bem-ruby("しきべつし")[識別子]として#bem-ruby("せんたく")[選択]したものである。#bem-ruby("こうほ")[候補]キーは#bem-ruby("ふくすう")[複数]#bem-ruby("そんざい")[存在]し#bem-ruby("う")[得]るが、#bem-ruby("しゅ")[主]キーとして#bem-ruby("せんたく")[選択]するものは#bem-ruby("ひと")[一]つである。


#bem-anno("Foreign key")[#bem-ruby("がいぶ")[外部]キー]とは、ある#bem-ruby("かんけい")[関係]の#bem-ruby("ぞくせいしゅうごう")[属性集合]であり、その#bem-ruby("あたい")[値]が#bem-ruby("どういつ")[同一]または#bem-ruby("べつ")[別]の#bem-ruby("かんけい")[関係]の#bem-ruby("こうほ")[候補]キーを#bem-ruby("さんしょう")[参照]する。たとえば、#raw("Student.department_id") が#bem-ruby("がくぶ")[学部]の#bem-ruby("かんけい")[関係]にある #raw("Department.department_id") を#bem-ruby("さんしょう")[参照]すれば、#bem-ruby("がくせい")[学生]と#bem-ruby("しょぞくがくぶ")[所属学部]を#bem-ruby("かんれん")[関連]づけられる。


== #bem-ruby("せいごうせいせいやく")[整合性制約]


#bem-anno("Integrity constraint")[#bem-ruby("せいごうせいせいやく")[整合性制約]]とは、データベースの#bem-ruby("じょうたい")[状態]が#bem-ruby("み")[満]たすべき#bem-ruby("じょうけん")[条件]である。#bem-ruby("だいひょうてき")[代表的]な#bem-ruby("せいやく")[制約]には、#bem-ruby("つぎ")[次]のものがある。


- ドメイン#bem-ruby("せいやく")[制約]は、#bem-ruby("ぞくせいち")[属性値]を#bem-ruby("しょてい")[所定]のドメインへ#bem-ruby("せいげん")[制限]する。

- キー#bem-ruby("せいやく")[制約]は、#bem-ruby("こうほ")[候補]キーの#bem-ruby("あたい")[値]がタプルを#bem-ruby("いちい")[一意]に#bem-ruby("しきべつ")[識別]することを#bem-ruby("ようきゅう")[要求]する。

- #bem-ruby("じったいせいごうせい")[実体整合性]は、#bem-ruby("しゅ")[主]キーの#bem-ruby("こうせいぞくせい")[構成属性]が#bem-ruby("けっそん")[欠損]せず、#bem-ruby("かく")[各]タプルを#bem-ruby("しきべつ")[識別]できることを#bem-ruby("ようきゅう")[要求]する。

- #bem-anno("Referential integrity")[#bem-ruby("さんしょうせいごうせい")[参照整合性]]は、#bem-ruby("がいぶ")[外部]キーの#bem-ruby("ひくう")[非空]の#bem-ruby("あたい")[値]が#bem-ruby("さんしょうさき")[参照先]に#bem-ruby("そんざい")[存在]することを#bem-ruby("ようきゅう")[要求]する。


DBMS はこれらの#bem-ruby("せいやく")[制約]に#bem-ruby("いはん")[違反]する#bem-ruby("こうしん")[更新]を#bem-ruby("きょひ")[拒否]し、または#bem-ruby("せんげん")[宣言]された#bem-ruby("さんしょうどうさ")[参照動作]に#bem-ruby("したが")[従]って#bem-ruby("かんれん")[関連]するデータを#bem-ruby("こうしん")[更新]する。ただし、データが#bem-ruby("げんじつせかい")[現実世界]を#bem-ruby("せいかく")[正確]に#bem-ruby("はんえい")[反映]しているかどうかは、スキーマに#bem-ruby("ひょうげん")[表現]された#bem-ruby("せいやく")[制約]だけでは#bem-ruby("かんぜん")[完全]に#bem-ruby("ほしょう")[保証]できない。


== #bem-ruby("せいきか")[正規化]の#bem-ruby("もくてき")[目的]


#bem-ruby("どういつ")[同一]の#bem-ruby("じじつ")[事実]を#bem-ruby("ふくすうかしょ")[複数箇所]へ#bem-ruby("きろく")[記録]すると、#bem-ruby("いちぶ")[一部]だけを#bem-ruby("こうしん")[更新]することによる#bem-ruby("ふせいごう")[不整合]、データを#bem-ruby("ついか")[追加]できない#bem-ruby("じょうきょう")[状況]、#bem-ruby("さくじょ")[削除]に#bem-ruby("ともな")[伴]う#bem-ruby("べつ")[別]の#bem-ruby("じじつ")[事実]の#bem-ruby("しょうしつ")[消失]が#bem-ruby("しょう")[生]じ#bem-ruby("う")[得]る。これらをそれぞれ#bem-ruby("こうしん")[更新]、#bem-ruby("そうにゅう")[挿入]、#bem-ruby("さくじょ")[削除]の#bem-anno("Anomaly")[#bem-ruby("いじょう")[異常]]という。


#bem-anno("Normalization")[#bem-ruby("せいきか")[正規化]]とは、#bem-ruby("ぞくせいかん")[属性間]の#bem-ruby("いぞんかんけい")[依存関係]に#bem-ruby("もと")[基]づいて#bem-ruby("かんけい")[関係]スキーマを#bem-ruby("ぶんかい")[分解]し、#bem-ruby("のぞ")[望]ましくない#bem-ruby("じょうちょうせい")[冗長性]と#bem-ruby("こうしんいじょう")[更新異常]を#bem-ruby("よくせい")[抑制]するための#bem-ruby("せっけいかてい")[設計過程]である。#bem-ruby("せいきか")[正規化]はあらゆる#bem-ruby("ちょうふく")[重複]を#bem-ruby("しょうきょ")[消去]することではなく、#bem-ruby("いぞんかんけい")[依存関係]を#bem-ruby("てきせつ")[適切]に#bem-ruby("ひょうげん")[表現]することを#bem-ruby("もくてき")[目的]とする。#bem-ruby("せいのう")[性能]や#bem-ruby("りようけいたい")[利用形態]に#bem-ruby("おう")[応]じて、#bem-ruby("いとてき")[意図的]に#bem-ruby("じょうちょうせい")[冗長性]を#bem-ruby("どうにゅう")[導入]する#bem-ruby("ひせいきか")[非正規化]もある。


== トランザクションと ACID


#bem-anno("Transaction")[トランザクション]とは、DBMS が#bem-ruby("ひと")[一]つの#bem-ruby("ろんりてき")[論理的]な#bem-ruby("さぎょうたんい")[作業単位]として#bem-ruby("あつか")[扱]う#bem-ruby("そうされつ")[操作列]である。たとえば#bem-ruby("そうきん")[送金]では、#bem-ruby("いっぽう")[一方]の#bem-ruby("こうざ")[口座]からの#bem-ruby("げんがく")[減額]と#bem-ruby("たほう")[他方]の#bem-ruby("こうざ")[口座]への#bem-ruby("ぞうがく")[増額]を#bem-ruby("いったい")[一体]として#bem-ruby("しょり")[処理]する#bem-ruby("ひつよう")[必要]がある。


トランザクションの#bem-ruby("だいひょうてき")[代表的]な#bem-ruby("とくせい")[特性]を ACID と#bem-ruby("そうしょう")[総称]する。


- #bem-anno("Atomicity")[#bem-ruby("げんしせい")[原子性]]: トランザクションの#bem-ruby("ぜんそうさ")[全操作]を#bem-ruby("はんえい")[反映]するか、いずれも#bem-ruby("はんえい")[反映]しない。

- #bem-anno("Consistency")[#bem-ruby("いっかんせい")[一貫性]]: トランザクションが#bem-ruby("ただ")[正]しく#bem-ruby("じっこう")[実行]されると、#bem-ruby("せいやく")[制約]を#bem-ruby("み")[満]たす#bem-ruby("じょうたい")[状態]から#bem-ruby("べつ")[別]のそのような#bem-ruby("じょうたい")[状態]へ#bem-ruby("いこう")[移行]する。

- #bem-anno("Isolation")[#bem-ruby("どくりつせい")[独立性]]: #bem-ruby("へいこう")[並行]するトランザクションの#bem-ruby("かんしょう")[干渉]を#bem-ruby("せいぎょ")[制御]し、#bem-ruby("しょてい")[所定]の#bem-ruby("ぶんり")[分離]レベルに#bem-ruby("たいおう")[対応]する#bem-ruby("かんそくけっか")[観測結果]を#bem-ruby("ていきょう")[提供]する。

- #bem-anno("Durability")[#bem-ruby("えいぞくせい")[永続性]]: #bem-ruby("かくてい")[確定]したトランザクションの#bem-ruby("けっか")[結果]は、#bem-ruby("いご")[以後]の#bem-ruby("しょうがい")[障害]に#bem-ruby("たい")[対]して#bem-ruby("ほじ")[保持]される。


ACID は#bem-ruby("じっそうほうしき")[実装方式]そのものではなく、トランザクション#bem-ruby("しょり")[処理]が#bem-ruby("もくひょう")[目標]とする#bem-ruby("せいしつ")[性質]である。また、#bem-ruby("いっかんせい")[一貫性]は DBMS だけで#bem-ruby("じどうてき")[自動的]に#bem-ruby("え")[得]られるものではなく、#bem-ruby("てきせつ")[適切]な#bem-ruby("せいやく")[制約]と#bem-ruby("ただ")[正]しいトランザクション#bem-ruby("しょり")[処理]を#bem-ruby("ひつよう")[必要]とする。


== #bem-ruby("ようてん")[要点]


- データベースは#bem-ruby("そしきか")[組織化]されたデータであり、DBMS はその#bem-ruby("ていぎ")[定義]、#bem-ruby("そうさ")[操作]、#bem-ruby("ほご")[保護]を#bem-ruby("にな")[担]う。

- #bem-ruby("かんけい")[関係]スキーマは#bem-ruby("ぞくせい")[属性]の#bem-ruby("こうせい")[構成]を#bem-ruby("さだ")[定]め、#bem-ruby("かんけい")[関係]インスタンスはある#bem-ruby("じてん")[時点]のタプルの#bem-ruby("しゅうごう")[集合]である。

- #bem-ruby("こうほ")[候補]キー、#bem-ruby("しゅ")[主]キー、#bem-ruby("がいぶ")[外部]キー、および#bem-ruby("せいごうせいせいやく")[整合性制約]は、データの#bem-ruby("しきべつ")[識別]と#bem-ruby("かんれん")[関連]を#bem-ruby("ひょうげん")[表現]する。

- #bem-ruby("せいきか")[正規化]は#bem-ruby("のぞ")[望]ましくない#bem-ruby("じょうちょうせい")[冗長性]と#bem-ruby("こうしんいじょう")[更新異常]を#bem-ruby("よくせい")[抑制]し、トランザクションは#bem-ruby("ふくすう")[複数]の#bem-ruby("そうさ")[操作]を#bem-ruby("ろんりてき")[論理的]な#bem-ruby("たんい")[単位]として#bem-ruby("かんり")[管理]する。


== #bem-ruby("つぎ")[次]に#bem-ruby("すす")[進]む#bem-ruby("こうぎ")[講義]


#block(above: 1.35em, below: 1.0em, width: 100%)[
#link("https://study.bem130.com/lecture/information/database/sql-basics.lecture/")[#box(width: 100%, inset: (x: 7pt, y: 5pt), stroke: 0.55pt + rgb("d8dee8"), radius: 3pt, fill: rgb("fbfcfe"))[
#set par(justify: false, leading: 0.35em)
#text(size: 7pt, fill: rgb("5d7796"))[→]#h(0.32em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("f4f6f9"), stroke: 0.45pt + rgb("d7dde6"))[#text(size: 6.8pt, fill: rgb("54657a"))[basics.lecture]]#h(0.32em)#text(size: 9.2pt, weight: 700, fill: rgb("182232"))[SQL の基本]#h(0.5em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[lecture]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[information]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[database]]#h(0.24em) \
#text(size: 7pt, fill: rgb("5d7796"))[https://study.bem130.com/lecture/information/database/sql-basics.lecture/]
]]
]


#pagebreak()


#block(above: 0.1em, below: 0.45em, width: 100%)[#text(size: 7pt, fill: luma(125))[data/lecture/information/database/sql-basics.lecture.n.md#h(0.7em)md eb2aeb2]]


= SQL の#bem-ruby("きほん")[基本]


#block(above: 1.35em, below: 1.0em, width: 100%)[
#link("https://study.bem130.com/lecture/information/database/database-basics.lecture/")[#box(width: 100%, inset: (x: 7pt, y: 5pt), stroke: 0.55pt + rgb("d8dee8"), radius: 3pt, fill: rgb("fbfcfe"))[
#set par(justify: false, leading: 0.35em)
#text(size: 7pt, fill: rgb("5d7796"))[→]#h(0.32em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("f4f6f9"), stroke: 0.45pt + rgb("d7dde6"))[#text(size: 6.8pt, fill: rgb("54657a"))[basics.lecture]]#h(0.32em)#text(size: 9.2pt, weight: 700, fill: rgb("182232"))[データベースの基本]#h(0.5em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[lecture]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[information]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[database]]#h(0.24em) \
#text(size: 7pt, fill: rgb("5d7796"))[https://study.bem130.com/lecture/information/database/database-basics.lecture/]
]]
]


== #bem-ruby("どうにゅう")[導入]


この#bem-ruby("こうぎ")[講義]では、#bem-ruby("かんけい")[関係]データベースに#bem-ruby("たい")[対]する#bem-ruby("と")[問]い#bem-ruby("あ")[合]わせと#bem-ruby("こうしん")[更新]を#bem-ruby("せんげんてき")[宣言的]に#bem-ruby("きじゅつ")[記述]する #bem-anno("Structured Query Language")[SQL] の#bem-ruby("きほん")[基本]を#bem-ruby("せつめい")[説明]する。#bem-ruby("ぜんこうぎ")[前講義]で#bem-ruby("どうにゅう")[導入]した#bem-ruby("ひょう")[表]、#bem-ruby("ぎょう")[行]、#bem-ruby("れつ")[列]、#bem-ruby("しゅ")[主]キー、#bem-ruby("がいぶ")[外部]キーを、SQL の#bem-ruby("こうぶん")[構文]と#bem-ruby("たいおう")[対応]させる。


SQL は、データへ#bem-ruby("とうたつ")[到達]する#bem-ruby("てじゅん")[手順]ではなく、#bem-ruby("ひつよう")[必要]な#bem-ruby("けっか")[結果]の#bem-ruby("じょうけん")[条件]を#bem-ruby("きじゅつ")[記述]する。#bem-ruby("さくいん")[索引]の#bem-ruby("りよう")[利用]や#bem-ruby("けつごうじゅんじょ")[結合順序]などの#bem-ruby("じっこうけいかく")[実行計画]は、#bem-ruby("つうじょう")[通常]、データベース#bem-ruby("かんり")[管理]システムが#bem-ruby("けってい")[決定]する。この#bem-ruby("せんげんせい")[宣言性]により、#bem-ruby("ろんりてき")[論理的]な#bem-ruby("と")[問]い#bem-ruby("あ")[合]わせと#bem-ruby("ぶつりてき")[物理的]な#bem-ruby("じっこうほうほう")[実行方法]を#bem-ruby("ぶんり")[分離]できる。


== SELECT、FROM、WHERE


#bem-ruby("きほんてき")[基本的]な#bem-ruby("と")[問]い#bem-ruby("あ")[合]わせは、#raw("SELECT")、#raw("FROM")、#raw("WHERE") の#bem-ruby("さんようそ")[三要素]から#bem-ruby("こうせい")[構成]される。


- #raw("FROM") は、#bem-ruby("と")[問]い#bem-ruby("あ")[合]わせの#bem-ruby("たいしょう")[対象]となる#bem-ruby("ひょう")[表]を#bem-ruby("してい")[指定]する。

- #raw("WHERE") は、#bem-ruby("かくぎょう")[各行]を#bem-ruby("じょうけんしき")[条件式]によって#bem-ruby("せんたく")[選択]する。この#bem-ruby("そうさ")[操作]を#bem-anno("Selection")[#bem-ruby("せんたく")[選択]]またはフィルタリングという。

- #raw("SELECT") は、#bem-ruby("けっか")[結果]に#bem-ruby("ふく")[含]める#bem-ruby("れつ")[列]または#bem-ruby("しき")[式]を#bem-ruby("してい")[指定]し、#bem-ruby("おおむ")[概]ね#bem-anno("Projection")[#bem-ruby("しゃえい")[射影]]に#bem-ruby("たいおう")[対応]する。ただし、SQLは#bem-ruby("きてい")[既定]で#bem-ruby("ちょうふくぎょう")[重複行]を#bem-ruby("ほじ")[保持]し、#raw("SELECT DISTINCT")を#bem-ruby("してい")[指定]した#bem-ruby("ばあい")[場合]に#bem-ruby("ちょうふく")[重複]を#bem-ruby("じょきょ")[除去]する。これは#bem-ruby("かんけいだいすう")[関係代数]の#bem-ruby("しゅうごう")[集合]としての#bem-ruby("しゃえい")[射影]との#bem-ruby("そうい")[相違]である。


#bem-ruby("ろんりてき")[論理的]には #raw("FROM") で#bem-ruby("たいしょう")[対象]を#bem-ruby("さだ")[定]め、#raw("WHERE") で#bem-ruby("ぎょう")[行]を#bem-ruby("せんたく")[選択]し、#raw("SELECT") で#bem-ruby("れつ")[列]を#bem-ruby("しゃえい")[射影]すると#bem-ruby("かいしゃく")[解釈]できる。これは#bem-ruby("がいねんじょう")[概念上]の#bem-ruby("やくわり")[役割]であり、データベース#bem-ruby("かんり")[管理]システムがこの#bem-ruby("じゅんじょ")[順序]で#bem-ruby("ぶつりてき")[物理的]に#bem-ruby("しょり")[処理]するとは#bem-ruby("かぎ")[限]らない。


#block(fill: luma(245), inset: 8pt, radius: 4pt, width: 100%)[
```sql
SELECT student_id, name
FROM students
WHERE department = 'Computer Science';
```
]


この#bem-ruby("と")[問]い#bem-ruby("あ")[合]わせは、#raw("students") #bem-ruby("ひょう")[表]から#bem-ruby("しょぞく")[所属]が #raw("Computer Science") である#bem-ruby("ぎょう")[行]を#bem-ruby("せんたく")[選択]し、その #raw("student_id") と #raw("name") を#bem-ruby("けっかれつ")[結果列]として#bem-ruby("してい")[指定]する。#bem-ruby("ちょうふくぎょう")[重複行]は#raw("DISTINCT")を#bem-ruby("してい")[指定]しない#bem-ruby("かぎ")[限]り#bem-ruby("ほじ")[保持]される。


== #bem-ruby("けっか")[結果]の#bem-ruby("じゅんじょ")[順序]


SQL の#bem-ruby("と")[問]い#bem-ruby("あ")[合]わせ#bem-ruby("けっか")[結果]には、#raw("ORDER BY") を#bem-ruby("してい")[指定]しない#bem-ruby("かぎ")[限]り#bem-ruby("じゅんじょ")[順序]の#bem-ruby("ほしょう")[保証]がない。#bem-ruby("どういつ")[同一]の#bem-ruby("と")[問]い#bem-ruby("あ")[合]わせでも、#bem-ruby("じっこうけいかく")[実行計画]やデータの#bem-ruby("はいち")[配置]によって#bem-ruby("ひょうじじゅん")[表示順]が#bem-ruby("へんか")[変化]し#bem-ruby("う")[得]る。


#block(fill: luma(245), inset: 8pt, radius: 4pt, width: 100%)[
```sql
SELECT student_id, name
FROM students
ORDER BY student_id ASC;
```
]


#bem-ruby("さいげんかのう")[再現可能]な#bem-ruby("じゅんじょ")[順序]が#bem-ruby("ひつよう")[必要]な#bem-ruby("ばあい")[場合]は、#bem-ruby("どうじゅんい")[同順位]を#bem-ruby("かいしょう")[解消]できる#bem-ruby("れつ")[列]まで #raw("ORDER BY") に#bem-ruby("してい")[指定]する。


== NULL と#bem-ruby("さんちろんり")[三値論理]


#raw("NULL") は、#bem-ruby("あたい")[値]が#bem-ruby("そんざい")[存在]しない、または#bem-ruby("ふめい")[不明]であることを#bem-ruby("あらわ")[表]す#bem-ruby("ひょうしき")[標識]であり、#bem-ruby("からもじれつ")[空文字列]や#bem-ruby("すうち")[数値]の 0 ではない。#raw("NULL") を#bem-ruby("ふく")[含]む#bem-ruby("つうじょう")[通常]の#bem-ruby("ひかく")[比較]は、#raw("TRUE") または #raw("FALSE") ではなく #raw("UNKNOWN") となる。SQL の#bem-ruby("じょうけんしき")[条件式]は、この#bem-anno("Three-valued logic")[#bem-ruby("さんちろんり")[三値論理]]に#bem-ruby("したが")[従]う。


#raw("WHERE") が#bem-ruby("けっか")[結果]に#bem-ruby("のこ")[残]すのは、#bem-ruby("じょうけんしき")[条件式]が #raw("TRUE") となる#bem-ruby("ぎょう")[行]だけである。#raw("FALSE") と #raw("UNKNOWN") の#bem-ruby("ぎょう")[行]は#bem-ruby("じょがい")[除外]される。したがって、#raw("NULL") の#bem-ruby("けんさ")[検査]には #raw("= NULL") ではなく #raw("IS NULL") または #raw("IS NOT NULL") を#bem-ruby("しよう")[使用]する。


#block(fill: luma(245), inset: 8pt, radius: 4pt, width: 100%)[
```sql
SELECT student_id, name
FROM students
WHERE email IS NULL;
```
]


== JOIN とキー


#bem-ruby("べつべつ")[別々]の#bem-ruby("ひょう")[表]に#bem-ruby("かくのう")[格納]された#bem-ruby("かんれん")[関連]データは、#raw("JOIN") によって#bem-ruby("けつごう")[結合]できる。#bem-ruby("れい")[例]として、#raw("students.student_id") を#bem-ruby("しゅ")[主]キー、#raw("enrollments.student_id") をそれを#bem-ruby("さんしょう")[参照]する#bem-ruby("がいぶ")[外部]キーとする。


#block(fill: luma(245), inset: 8pt, radius: 4pt, width: 100%)[
```sql
SELECT s.student_id, s.name, e.course_id
FROM students AS s
JOIN enrollments AS e
  ON e.student_id = s.student_id
WHERE e.status = 'enrolled';
```
]


#raw("ON") は#bem-ruby("ふた")[二]つの#bem-ruby("ひょう")[表]の#bem-ruby("ぎょう")[行]を#bem-ruby("たいおう")[対応]させる#bem-ruby("けつごうじょうけん")[結合条件]を#bem-ruby("してい")[指定]する。#bem-ruby("しゅ")[主]キーの#bem-ruby("いちいせい")[一意性]と#bem-ruby("がいぶ")[外部]キーの#bem-ruby("さんしょうせいごうせい")[参照整合性]により、この#bem-ruby("たいおうかんけい")[対応関係]をデータベース#bem-ruby("がわ")[側]で#bem-ruby("けんしょう")[検証]できる。ただし、#raw("JOIN") #bem-ruby("じたい")[自体]は#bem-ruby("がいぶ")[外部]キーが#bem-ruby("せんげん")[宣言]されていなくても#bem-ruby("じっこうかのう")[実行可能]である。


== #bem-ruby("こうしん")[更新]、#bem-ruby("せいやく")[制約]、トランザクション


SQL は、#raw("INSERT") で#bem-ruby("ぎょう")[行]を#bem-ruby("ついか")[追加]し、#raw("UPDATE") で#bem-ruby("きそんぎょう")[既存行]を#bem-ruby("へんこう")[変更]し、#raw("DELETE") で#bem-ruby("ぎょう")[行]を#bem-ruby("さくじょ")[削除]する。


#block(fill: luma(245), inset: 8pt, radius: 4pt, width: 100%)[
```sql
INSERT INTO enrollments (student_id, course_id, status)
VALUES (1001, 'CS101', 'enrolled');

UPDATE enrollments
SET status = 'completed'
WHERE student_id = 1001 AND course_id = 'CS101';

DELETE FROM enrollments
WHERE student_id = 1001 AND course_id = 'CS101';
```
]


#raw("PRIMARY KEY")、#raw("FOREIGN KEY")、#raw("UNIQUE")、#raw("NOT NULL")、#raw("CHECK") などの#bem-anno("Constraint")[#bem-ruby("せいやく")[制約]]は、#bem-ruby("きょよう")[許容]されるデータの#bem-ruby("じょうけん")[条件]をスキーマに#bem-ruby("きろく")[記録]し、#bem-ruby("ふせい")[不正]な#bem-ruby("こうしん")[更新]を#bem-ruby("きょひ")[拒否]する。ただし、#bem-ruby("せいやく")[制約]の#bem-ruby("ぐたいてき")[具体的]な#bem-ruby("きのう")[機能]や#bem-ruby("こうぶん")[構文]にはデータベース#bem-ruby("せいひん")[製品]による#bem-ruby("さい")[差異]がある。


#bem-ruby("ふくすう")[複数]の#bem-ruby("ぶん")[文]を#bem-ruby("いったい")[一体]の#bem-ruby("しょり")[処理]として#bem-ruby("あつか")[扱]う#bem-ruby("ばあい")[場合]は、#bem-anno("Transaction")[トランザクション]を#bem-ruby("しよう")[使用]する。#raw("COMMIT") はトランザクションの#bem-ruby("へんこう")[変更]を#bem-ruby("かくてい")[確定]し、#raw("ROLLBACK") は#bem-ruby("みかくてい")[未確定]の#bem-ruby("へんこう")[変更]を#bem-ruby("とりけ")[取消]す。これにより、#bem-ruby("しょり")[処理]の#bem-ruby("とちゅう")[途中]だけが#bem-ruby("はんえい")[反映]された#bem-ruby("じょうたい")[状態]を#bem-ruby("かいひ")[回避]できる。ただし、トランザクションの#bem-ruby("ぶんり")[分離]レベルや#bem-ruby("じどうかくてい")[自動確定]の#bem-ruby("きていち")[既定値]は#bem-ruby("じっそう")[実装]によって#bem-ruby("こと")[異]なる。


== パラメータ#bem-ruby("か")[化]と#bem-ruby("あんぜんせい")[安全性]


#bem-ruby("りようしゃ")[利用者]の#bem-ruby("にゅうりょく")[入力]を SQL #bem-ruby("もじれつ")[文字列]へ#bem-ruby("ちょくせつれんけつ")[直接連結]すると、#bem-ruby("にゅうりょく")[入力]が SQL の#bem-ruby("こうぶん")[構文]として#bem-ruby("かいしゃく")[解釈]される SQL インジェクションを#bem-ruby("まね")[招]き#bem-ruby("う")[得]る。#bem-ruby("あたい")[値]は、#bem-ruby("しよう")[使用]するドライバが#bem-ruby("ていきょう")[提供]するパラメータ#bem-ruby("か")[化]された#bem-ruby("と")[問]い#bem-ruby("あ")[合]わせへ#bem-ruby("べっと")[別途]#bem-ruby("わた")[渡]す。


#block(fill: luma(245), inset: 8pt, radius: 4pt, width: 100%)[
```sql
SELECT student_id, name
FROM students
WHERE email = ?;
```
]


#raw("?") はパラメータの#bem-ruby("がいねんれい")[概念例]であり、#bem-ruby("じっさい")[実際]のプレースホルダ#bem-ruby("こうぶん")[構文]はドライバやデータベース#bem-ruby("せいひん")[製品]によって#bem-ruby("こと")[異]なる。パラメータ#bem-ruby("か")[化]は#bem-ruby("あたい")[値]と SQL #bem-ruby("こうぶん")[構文]を#bem-ruby("ぶんり")[分離]するが、#bem-ruby("ひょうめい")[表名]や#bem-ruby("れつめい")[列名]などの#bem-ruby("しきべつし")[識別子]を#bem-ruby("にんい")[任意]に#bem-ruby("あんぜんか")[安全化]するものではない。#bem-ruby("しきべつし")[識別子]を#bem-ruby("どうてき")[動的]に#bem-ruby("せんたく")[選択]する#bem-ruby("ばあい")[場合]は、#bem-ruby("きょか")[許可]リストによる#bem-ruby("けんしょう")[検証]などが#bem-ruby("ひつよう")[必要]である。また、#bem-ruby("にんか")[認可]、#bem-ruby("さいしょうけんげん")[最小権限]、#bem-ruby("きみつじょうほう")[機密情報]の#bem-ruby("ほご")[保護]も#bem-ruby("べっとひつよう")[別途必要]となる。


== #bem-ruby("ようてん")[要点]


- SQL は、#bem-ruby("ひつよう")[必要]な#bem-ruby("けっか")[結果]を#bem-ruby("せんげん")[宣言]し、その#bem-ruby("ぶつりてき")[物理的]な#bem-ruby("じっこうほうほう")[実行方法]をデータベース#bem-ruby("かんり")[管理]システムへ#bem-ruby("ゆだ")[委]ねる。

- #raw("WHERE") は#bem-ruby("ぎょう")[行]を#bem-ruby("せんたく")[選択]し、#raw("SELECT") は#bem-ruby("けっか")[結果]の#bem-ruby("れつ")[列]や#bem-ruby("しき")[式]を#bem-ruby("してい")[指定]する。SQLは#bem-ruby("きてい")[既定]で#bem-ruby("ちょうふくぎょう")[重複行]を#bem-ruby("ほじ")[保持]する。#raw("NULL") を#bem-ruby("ふく")[含]む#bem-ruby("じょうけん")[条件]には#bem-ruby("さんちろんり")[三値論理]が#bem-ruby("てきよう")[適用]される。

- #raw("JOIN") は#bem-ruby("ふくすう")[複数]の#bem-ruby("ひょう")[表]を#bem-ruby("かんれんづ")[関連付]け、キーと#bem-ruby("せいやく")[制約]はデータの#bem-ruby("せいごうせい")[整合性]を#bem-ruby("ささ")[支]える。

- #bem-ruby("こうしん")[更新]はトランザクションによって#bem-ruby("いったい")[一体]として#bem-ruby("かんり")[管理]でき、#bem-ruby("がいぶにゅうりょく")[外部入力]はパラメータ#bem-ruby("か")[化]して SQL #bem-ruby("こうぶん")[構文]から#bem-ruby("ぶんり")[分離]する。

- #raw("ORDER BY") のない#bem-ruby("けっか")[結果]に#bem-ruby("じゅんじょ")[順序]の#bem-ruby("ほしょう")[保証]はない。


== #bem-ruby("つぎ")[次]に#bem-ruby("すす")[進]む#bem-ruby("こうぎ")[講義]


#block(above: 1.35em, below: 1.0em, width: 100%)[
#link("https://study.bem130.com/lecture/information/software-engineering/software-engineering-portal.lecture/")[#box(width: 100%, inset: (x: 7pt, y: 5pt), stroke: 0.55pt + rgb("d8dee8"), radius: 3pt, fill: rgb("fbfcfe"))[
#set par(justify: false, leading: 0.35em)
#text(size: 7pt, fill: rgb("5d7796"))[→]#h(0.32em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("f4f6f9"), stroke: 0.45pt + rgb("d7dde6"))[#text(size: 6.8pt, fill: rgb("54657a"))[portal.lecture]]#h(0.32em)#text(size: 9.2pt, weight: 700, fill: rgb("182232"))[software-engineering]#h(0.5em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[lecture]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[information]]#h(0.24em)#box(inset: (x: 3.8pt, y: 1.5pt), radius: 6pt, fill: rgb("eef6ff"), stroke: 0.45pt + rgb("9cc8f7"))[#text(size: 6.8pt, fill: rgb("215f9f"))[software-engineering]]#h(0.24em) \
#text(size: 7pt, fill: rgb("5d7796"))[https://study.bem130.com/lecture/information/software-engineering/software-engineering-portal.lecture/]
]]
]
