質問

挿入が簡単になるように、リンクされたリストを mysql データベースに保存する最良の方法は何ですか (つまり、毎回大量のインデックスを再作成する必要はありません)、リストを順番に簡単に取り出すことができます。

役に立ちましたか?

解決

「position」という名前の整数列をテーブルに保存します。リストの最初の項目には 0、2 番目の項目には 1 などを記録します。データベース内のその列にインデックスを付け、値を取り出したい場合は、その列で並べ替えます。

 alter table linked_list add column position integer not null default 0;
 alter table linked_list add index position_index (position);
 select * from linked_list order by position;

インデックス 3 に値を挿入するには、行 3 以降の位置を変更してから次を挿入します。

 update linked_list set position = position + 1 where position >= 3;
 insert into linked_list (my_value, position) values ("new value", 3); 

他のヒント

Adrian のソリューションを使用しますが、1 ずつ増分する代わりに、10 または 100 ずつ増分します。そうすれば、挿入の下のすべてを更新することなく、間に挿入しているものの半分の差で挿入を計算できます。平均挿入数を処理できる十分な大きさの数値を選択してください。数値が小さすぎる場合は、挿入中に上位の位置ですべての行を更新するようにフォールバックする必要があります。

PreviousID と NextID という 2 つの自己参照列を持つテーブルを作成します。項目がリストの最初の場合、PreviousID は null になり、それが最後の場合、NextID は null になります。SQL は次のようになります。

create table tblDummy
{
     PKColumn     int     not null, 
     PreviousID     int     null, 
     DataColumn1     varchar(50)     not null, 
     DataColumn2     varchar(50)     not null,  
     DataColumn3     varchar(50)     not null, 
     DataColumn4     varchar(50)     not null, 
     DataColumn5     varchar(50)     not null, 
     DataColumn6     varchar(50)     not null, 
     DataColumn7     varchar(50)     not null, 
     NextID     int     null
}

リンク リストは、再帰ポインタを使用してテーブルに保存できます。これは SQL に保存されている階層とほぼ同じであり、再帰的な関連付けパターンを使用しています。

さらに詳しく知ることができます ここ.

これがお役に立てば幸いです。

最も単純なオプションは、リスト項目ごとに行、項目の位置の列、項目内のその他のデータの列を含むテーブルを作成することです。次に、position 列で ORDER BY を使用して、希望の順序で取得できます。

create table linked_list
(   list_id   integer not null
,   position  integer not null 
,   data      varchar(100) not null
);
alter table linked_list add primary key ( list_id, position );

リストを操作するには、位置を更新し、必要に応じてレコードを挿入/削除するだけです。したがって、リスト 1 のインデックス 3 に項目を挿入するには、次のようにします。

begin transaction;

update linked_list set position = position + 1 where position >= 3 and list_id = 1;

insert into linked_list (list_id, position, data)
values (1, 3, "some data");

commit;

リストの操作には複数のコマンドが必要になる場合があるため (たとえば、挿入には INSERT と UPDATE が必要です)、必ずトランザクション内でコマンドを実行してください。

この単純なオプションのバリエーションとして、項目ごとに何らかの係数 (たとえば 100) で位置を増分することができます。これにより、INSERT を実行するときに、後続の要素の位置の番号を常に付け直す必要がなくなります。ただし、これには、後続の要素をいつインクリメントするかを考えるのに少し手間がかかるため、単純さは失われますが、多数の挿入がある場合はパフォーマンスが向上します。

要件に応じて、次のような他のオプションが魅力的な場合があります。

  • リストに対して多くの操作を実行し、あまり検索は行わない場合は、位置列を使用する代わりに、リスト内の次の項目を指す ID 列を使用することをお勧めします。次に、項目を順番に取得するために、リストの取得でロジックを反復する必要があります。これはストアド プロシージャで比較的簡単に実装できます。

  • 多数のリストがあり、リストをテキスト/バイナリにシリアル化および逆シリアル化する簡単な方法で、リスト全体を保存および取得するだけの場合は、リスト全体を 1 つの列に 1 つの値として保存します。おそらくここで求めているものはそうではありません。

この投稿は古いですが、それでも.02ドルを差し上げます。順序付けを解決するには、テーブルまたはレコード セット内のすべてのレコードを更新するのはクレイジーに思えます。インデックス作成の量も異常ですが、ほとんどの人がそれを受け入れているようです。

更新とインデックス作成を減らすために私が思いついたクレイジーな解決策は、2 つのテーブルを作成することです (そして、ほとんどのユースケースでは、とにかく 1 つのテーブルですべてのレコードを並べ替えることはありません)。ソート中のリストのレコードを保持するテーブル A と、順序のレコードをグループ化して文字列として保持するテーブル B です。順序文字列は、Web サーバーまたは Web ページ アプリケーションのブラウザ層で選択されたレコードを順序付けるために使用できる配列を表します。

Create Table A{
Id int primary key identity(1,1),
Data varchar(10) not null
B_Id int
}

Create Table B{
Id int primary key Identity(1,1),
GroupName varchat(10) not null,
Order varchar(max) null
}

オーダー文字列の形式は、文字列を分割するための ID、位置、およびセパレータである必要があります。jQuery UI の場合、 .sortable('serialize') 関数は、リスト内の各レコードの ID と位置を含む POST フレンドリーな順序文字列を出力します。

本当の魔法は、保存した順序付け文字列を使用して、選択したリストの順序を変更する方法です。これは、構築しているアプリケーションによって異なります。項目のリストを並べ替える jQuery の例をもう一度示します。 http://ovisdevelopment.com/oramincite/?p=155

https://dba.stackexchange.com/questions/46238/linked-list-in-sql-and-trees は、高速な挿入と順序付けのために浮動小数点位置列を使用するトリックを提案しています。

特殊な SQL Server 2014 についても言及されています。 階層ID 特徴。

私がすぐに思いつくアプローチはいくつかありますが、それぞれの複雑さと柔軟性のレベルが異なります。あなたの目標は、実際のリンクリストとしてストレージを必要とするのではなく、検索時に順序を保持することであると仮定しています。

最も単純な方法は、テーブル内の各レコードに順序値を割り当てることです (例:1、2、3、...)。次に、レコードを取得するときに、順序列に order-by を指定してレコードの順序を戻します。

このアプローチでは、リストのメンバーシップに関係なくレコードを取得することもできますが、メンバーシップが許可されるのは 1 つのリストのみであり、レコードがどのリストに属しているかを示す追加の「リスト ID」列が必要になる場合があります。

もう少し複雑ですが、より柔軟なアプローチは、リスト内のメンバーシップに関する情報を別のテーブルに保存することです。テーブルには 3 つの列が必要です。リスト ID、順序値、およびデータ レコードへの外部キー ポインター。このアプローチでは、基になるデータはリスト内のメンバーシップについて何も知らないため、複数のリストに簡単に含めることができます。

作成された列を追加する方がはるかに簡単だと思います Datetime タイプと位置列 int, ので、重複した位置を持つことができるようになりました。select ステートメントで order by 位置、作成された desc オプション、リストが順番に取得されます。

これは私自身、しばらくの間理解しようとしていたものです。私がこれまでに見つけた最良の方法は、次の形式を使用してリンク リスト用の 1 つのテーブルを作成することです (これは疑似コードです)。

リンクリスト(

  • キー1、
  • 情報、
  • キー2

)

key1 が開始点です。Key2 は、次の列のそれ自体にリンクする外部キーです。したがって、あなたの列は何かをリンクし、このようなものをリンクします

列1

  • キー1 = 0、
  • 情報= 'こんにちは'
  • キー2 = 1

Key1 は、col1 の主キーです。key2 は、col2 の key1 につながる外部キーです。

列2

  • キー1 = 1、
  • 情報= 'ワサップ'
  • キー2 = null

Col2 の key2 は何も指していないため、null に設定されます。

初めてテーブルに列を入力するときは、key2 が null に設定されていることを確認する必要があります。そうしないと、エラーが発生します。2 番目の列を入力した後、戻って最初の列の key2 を 2 番目の列の主キーに設定できます。

これは、一度に多くのエントリを入力し、戻ってそれに応じて外部キーを設定する (または、それを行うだけの GUI を構築する) 場合に最適な方法です。

以下に私が用意した実際のコードをいくつか示します (実際のコードはすべて MSSQL 上で動作しました)。使用している SQL のバージョンについて調べてみるとよいでしょう):

作成テーブル.sql

create table linkedlist00 (

key1 int primary key not null identity(1,1),

info varchar(10),

key2 int

)

register_foreign_key.sql

alter table dbo.linkedlist00

add foreign key (key2) references dbo.linkedlist00(key1)

※2ステップで行う必要があるため、2つのファイルに分けました。MSSQL では、外部キーが参照するテーブルがまだ存在しないため、これを 1 ステップで行うことはできません。

リンク リストは、次のような場合に特に強力です。 1対多 関係。では、外部キーの配列を作成したいと思ったことがあるでしょうか?まあ、これも一つの方法ですよ!リンク リスト テーブルの最初の列を指すプライマリ テーブルを作成し、「情報」フィールドの代わりに、目的の情報テーブルへの外部キーを使用できます。

例:

フォームを管理する官僚組織があるとします。

というテーブルがあるとします。 ファイルキャビネット

ファイルキャビネット(

  • キャビネット ID (パック)
  • ファイル ID (fk) )

各列には、キャビネットの主キーとファイルの外部キーが含まれています。これらのファイルには、納税フォーム、健康保険書類、フィールドトリップ許可票などが含まれます。

ファイル(

  • ファイルID (パック)

  • ファイルID (fk)

  • 次のファイル ID (fk)

)

これはファイルのコンテナとして機能します

ファイル(

  • ファイルID (パック)

  • ファイルに関する情報

)

これは特定のファイルです

特定のニーズに応じて、これを行うためのより良い方法があるかもしれません。この例は、可能な使用法を示しているだけです。

リストは、列にオフセット (リストのインデックス位置) を含めることによって格納できます。中央での挿入は、新しい親の上にすべてインクリメントしてから挿入を実行します。

SERIAL の「インデックス」を 100 ずつ増やしますが、Prev+Next / 2 に等しい「インデックス」を持つ中間値を手動で追加します。100 行が飽和状態になった場合は、インデックスの順序を 100 番台に戻してください。

これにより、プライマリ インデックスとの順序が維持されるはずです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top