SQLite で重複を防ぐ

Bilal Shahid 2023年6月21日
SQLite で重複を防ぐ

データベースにデータを入力する際に遭遇する可能性のある最も一般的な問題の 1つは、データの重複です。 これは、多くのユーザー、特に大規模なデータベースを使用するユーザーにとって問題になる可能性があります。

非常にコストがかかる可能性のあるメモリの浪費など、さまざまな問題が発生する可能性があります。

とにかく挿入中は理想的に避ける必要があります。 これにより、最初からアクセス データがデータベースに入力されるのを防ぐことができます。

SQLite で重複エントリを回避する方法

SQLite では、エントリの重複を避ける方法が複数あります。 これらの各方法を区別する主な理由は次のとおりです。

  1. 塗りやすさ。
  2. 有効率。
  3. データベースの要件。

手動削除

高度なデータベース クエリが登場する前は、エントリを調べて重複を特定するのが一般的でした。 これは、レコードが非常に少ないデータベースでも機能します。

ただし、これはすべての場合において非効率的であり、非常に大規模なデータベースには使用できません。 これらの問題が、この方法がほとんど使用されない理由です。

高度なネストされたクエリを使用する

高度なネストされたクエリは、正しく適用されれば何でも実行できます。 ただし、これも評価されないことが多いです。

それらの設計はしばしば複雑であり、すべての場合において正確であるとは限りません。 したがって、この方法は機能しますが、より単純な方法が存在するため、お勧めできません。

UNIQUE 制約

この制約は、テーブルの作成中に SQLite で適用されることがよくあります。 行に適用すると、ユーザーが同じ行のデータベースに重複したエントリを入力するのを防ぎます。

この制約は、主キー制約が使用されている場合にも自動的に適用されます。 次のコードを使用して、テーブルを作成し、一意の制約を適用できます。

CREATE TABLE users(
    users_id INTEGER,
    user_age INTEGER,
    UNIQUE(users_id, lessoninfo_id)
);

次のように直接適用することもできます。

CREATE TABLE users(
   users_id INTEGER UNIQUE,
    user_age INTEGER
);

既にテーブルを作成しており、行を一意にするために変更を加える必要がある場合は、テーブル全体を削除する必要があります。 以下のコードに示すように、一意のインデックスを選択することもできます。

CREATE UNIQUE INDEX index_name
ON users(users_id);

EXISTS

Exists は、クエリやネストされたクエリでよく使用されます。 複雑なクエリを単純化したクエリに簡単に変換できます。

その逆が NOT EXISTS 句で、これは正反対を意味します。 これは、以下に示すように、挿入後にクエリで使用できます。

まず、テーブルが既に作成されていることを確認します。 これを行うには、次のコードを使用できます。

CREATE TABLE users(
   users_id INTEGER,
    user_age INTEGER
);

この後、クエリの作成を開始します。 以下のコードを参照して、句を正しく使用できます。

SELECT *
FROM users
WHERE EXISTS
(
--any query with your preferred conditions
)

注: ここで、EXISTSNOT EXISTS に置き換えると、逆の結果が得られます。

以下で説明するように、句を別の方法で使用して、挿入中にこのロジックを直接適用することもできます。

NOT EXISTS の場合に挿入

データベース内のテーブルに値を挿入するクエリを作成する際、最もよく使用される最も一般的な方法は、存在しない場合は挿入を使用することです。

これは、データを挿入するクエリと組み合わせて not exists 句を使用するより良い方法と考えることができます。 この例を以下のコードに示します。

まず、テーブルを作成します。

CREATE TABLE users(
   users_id INTEGER,
    user_age INTEGER
);

次に、次のコードのようなクエリを設計します。

INSERT INTO users(users_id,user_age)
SELECT * /*user whose id isn't 1.*/
WHERE NOT EXISTS
(
SELECT 1 FROM memos WHERE id = 5 AND name= 'abc'
);

ラベルが示すように、このクエリは、ユーザー id が 1 ではないユーザーまたはデータ エントリのみを表示します。括弧内のクエリを要件に合わせて変更することで、いつでも条件を変更できます。

挿入または無視

SQLite に冗長性を追加するのをうまく防ぐもう 1つの方法は、insert or ignore 句です。 挿入が定義済みの用語に違反する場合、挿入は無視されます。

クエリは正常に実行されますが、挿入は行われません。

primary key が存在する別の例を見てみましょう。 primary key には一意の制約が存在します。つまり、重複したエントリは受け入れられません。

次のように、最初に 主キー を使用してテーブルが作成されます。

CREATE TABLE users
(
id INTEGER NOT NULL PRIMARY KEY,
age INTEGER
);

以下に示すように、ignore 条件で値を挿入できます。

INSERT OR IGNORE
INTO users(id, age) VALUES(123, 24)

ID 123 を持つユーザーが既に存在すると仮定すると、この挿入は行われず、元のテーブルは変更されません。

注: 値を挿入する列に一意の制約がない場合、レコードは常に挿入されます。

REPLACE

ignore 句を使用する代わりに、それを置き換えることもできます。 これは ignore 句に似ています。一意の制約 (または 主キー) が特定の行に適用されている場合、挿入された値が一意であるかどうかを最初にチェックします。

ここでの違いは、一意の制約を持つレコードが既に存在する場合、挿入する新しいレコードに置き換えられることです。

INSERT OR REPLACE
INTO users(id, age) VALUES(123, abc)

ここで、ID 123 を持つユーザーが既にテーブルに存在する場合、名前は abc に置き換えられます。

SQLite でエントリの重複を避けるために知っておくべきことはこれですべてです。 ニーズを満たし、最も効率的なデータベースを作成するために何をすべきかを正確に理解していただけたことを願っています。

著者: Bilal Shahid
Bilal Shahid avatar Bilal Shahid avatar

Hello, I am Bilal, a research enthusiast who tends to break and make code from scratch. I dwell deep into the latest issues faced by the developer community and provide answers and different solutions. Apart from that, I am just another normal developer with a laptop, a mug of coffee, some biscuits and a thick spectacle!

GitHub

関連記事 - SQLite Insert