0

個人テーブルにauthorized_areasというフィールドがあるデータベースを継承しました。フロントエンドを使用すると、ユーザーは選択リスト(エリアテーブルの説明フィールドの値が入力されます)から複数のエントリを選択し、authorized_areasの値をコンマ区切りのリストに設定できます。これをMySQLデータベースに移行しています。その間、personテーブルからauthorized_areasフィールドを削除し、personのペアを保持するだけの多対多のテーブルperson_areaを作成して、データベースの整合性を向上させたいと考えています。 -エリアキー。数百人のレコードがあるので、個々の挿入または更新ステートメントではなく、いくつかのMySQLステートメントを使用してこれを効率的に行う方法を見つけたいと思います。

明確にするために、現在の構造は次のようなものです。

person
id    name    authorised_areas
1     Joe     room12, room153, 2nd floor office
2     Anna    room12, room17

area
id    description
1     room12
2     room17
3     room153
4     2nd floor office

...しかし、私が欲しいのは:

person
id    name
1     Joe
2     Anna

area
id    description
1     room12
2     room17
3     room153
4     2nd floor office

person_area
person_id     area_id
1             1
1             3
1             4
2             1
2             2

人物テーブルにはエリアIDへの参照がないため(リスト内の一部のテキスト値はエリアテーブル内の説明と完全に同じではありません)、これはテキストまたはパターンマッチングによって行う必要があります。いくつかのphpコードを記述して文字列を分割し、一致するものを見つけて、適切な値を多対多のテーブルに挿入する方がよいでしょうか。

私がこれをしなければならなかった最初の人だったら私は驚きます、しかしグーグル検索は何も有用なものを見つけませんでした(おそらく私は適切な検索用語を使用しませんでしたか?)これを効率的に行うために、私はそれを非常に高く評価します。

4

1 に答える 1

0

これを行うことは可能ですが、1回限りの作業として、php(またはお気に入りのスクリプト言語)スクリプトをノックアップして、複数の挿入を使用する方がおそらく速いことをお勧めします。

単一のステートメントでそれを行う必要がある場合は、整数のテーブル(0〜9、必要なだけ大きな範囲を取得するためにそれ自体に対してクロス結合)を作成し、文字列関数を使用してX番目のコンマを取得して元のテーブルに対してこれを結合しますそして、そこから各行の各値。

可能であり、私はそれを実行しましたが、主に、区切られたフィールドを持つことは良い考えではないことを示すためです。複数の挿入があるスクリプトをノックアップする方がはるかに速いでしょう。

このSELECTのようなものに基づいて挿入を行うことができます(ただし、これには、各人と関連する人の空白行が表示され、1人あたり最大1000の許可された領域にしか対応しません)

SELECT z.id, z.name, x.an_authorised_area
FROM person z
LEFT OUTER JOIN (
SELECT DISTINCT a.id, SUBSTRING_INDEX( SUBSTRING_INDEX( authorised_areas, ",", b.ournumbers ) , ",", -1 ) AS an_authorised_area
FROM person a, (
SELECT hundreds.i *100 + tens.i *10 + units.i AS ournumbers
FROM integers AS hundreds
CROSS JOIN integers AS tens
CROSS JOIN integers AS units
)b
)x ON z.id = x.id
于 2012-10-19T11:47:22.927 に答える