0

解決策が見つからないような問題があります。私はこの辺りで同様の答えを閲覧しましたが、私が探していたものは何もありませんでした。私はSQLにかなり精通していますが、決して専門家ではありません。

私はアパートの建物に関する情報(名前、地域、近所、電話番号、住所、郵便番号など)を含むテーブルを持っています。現在、このテーブル内には「ドアマン」、「エレベーター」、「ジム」などのいくつかの設備が定義されています。と他のいくつか)建物が実際にその快適さを持っているかどうかを示すためのtinyintsとして。しかし、私はさらに多くの種類のアメニティを組み込む過程にあり、巨大な建物のテーブルに列を追加することはあまり意味がないため、構造を変更する時期かもしれないと考えました。

だから私は次のことを行うための最高の能力を私に提供する解決策を探しています:1)ユーザー定義の設備に基づいて建物を検索します(たとえば、ユーザーはジムとドアマンが必要な建物を見たいと選択します、他の人は気にしない)2)建物に含まれるすべての設備を含む建物に関するデータを返す(情報を表示するため)

これらの構造を多対多の関係に分離し、次のことを行うことを考えていました。1)すべてのアメニティを含む「アメニティ」と呼ばれる新しいテーブルを作成すると、次の構造になります。id->アメニティ名の一意のID->アメニティ値のテキスト説明->たとえば「pet_friendly」(フォームで検索する場合、必要かどうかわからない)

2)次の構造を持つ「building_amenities」と呼ばれる別のテーブルに建物とアメニティの関係テーブルを作成します。id->関係の一意のIDbuilding_id->建物のIDを参照amenity_id->アメニティのIDを参照value-> tinyint、建物にアメニティがあるかどうかこの表では、各建物は各アメニティと関係があり、アメニティがあるかどうかを示します。

私の問題は、これがこの状況に適した構造であるかどうかわからないことです。この構造があった場合、検索クエリをどのように実装するかは確かにわかりません。

これについて助けてくれてありがとう!

4

3 に答える 3

1

建物テーブル、アメニティテーブル、リレーショナルテーブルを作成することをお勧めします。各建物にはIDがあり、各アメニティにもIDがあります。特定の設備が存在するすべての建物を選択するには、次のようにクエリを作成するだけです。

SELECT *
FROM (relational_table) rt JOIN (buildings_table) bt
    ON rt.id_building = bt.id_building JOIN (amenities_table) at
    ON at.id_amenity = rt.id_amenity
WHERE rt.id_amenity = ... (OR, AND etc.)

アメニティを備えた建物を返却するには、WHERE句をWHERE id_building = xに変更するだけで、ですべてのアメニティを選択する必要があります。

于 2012-04-13T21:57:25.840 に答える
0

building_amenitiesテーブルにtinyintフラグ以外のすべてがあります。アメニティが実際にそこにあった場合にのみ、そのテーブルにレコードがあります。

このように、通常の結合を使用して、特定のアメニティを持つすべての建物を検索するクエリを作成できます。

select * from buildings
    join building_amenities on buildings.id=building_amenities.building_id
    join amenities on building_amenities.amenity_id=amenities.id
where amenities.name='doorman'

(たとえば)ドアマンなしで建物を取得したい場合は、左結合を使用できます。

select * from amenities
    left join building_amenities on amenities.id=building_amenities.amenity_id
    left join buildings on building_amenities.buildings_id=buildings.id
where buildings.id is NULL and amenities.name='doorman'
于 2012-04-13T21:58:40.013 に答える
0

Phil Cairnsによってすでに提案されているように、関連付けテーブルにTINYINT(疑似ブール値)を含めるべきではありません。建物にアメニティが存在する場合にのみ、関連付けテーブルにレコードが存在する必要があります。

複数の結合を使用するとパフォーマンスは向上しますが、GROUP BY ... HAVING COUNTを使用すると、同じ(またはわずかに優れた)パフォーマンスを得ることができ、複数の条件のクエリを操作する方がはるかに簡単です。

したがって、アメニティ1、2、4を備えたすべての建物を検索したい場合は、次のことができます-

SELECT b.*
FROM buildings b
INNER JOIN building_amenities ba
    ON b.id = ba.building_id
WHERE ba.amenity_id IN (1,2,4)
GROUP BY b.id
HAVING COUNT(ab.amenity_id) = 3

アメニティ1、2、4、7、13、19、23のあるすべての建物を検索する場合、クエリは次のようになります-

SELECT b.*
FROM buildings b
INNER JOIN building_amenities ba
    ON b.id = ba.building_id
WHERE ba.amenity_id IN (1,2,4,7,13,19,23)
GROUP BY b.id
HAVING COUNT(ab.amenity_id) = 7

また、建物のすべてのアメニティを表示する必要がある場合は、アメニティテーブルに2番目の結合を追加できます-

SELECT b.*, GROUP_CONCAT(DISTINCT ab2.amenity_id)
FROM buildings b
INNER JOIN building_amenities ba
    ON b.id = ba.building_id
INNER JOIN building_amenities ba2
    ON b.id = ba2.building_id
WHERE ba.amenity_id IN (1,2,4,7,13,19,23)
GROUP BY b.id
HAVING COUNT(DISTINCT ab.amenity_id) = 7
于 2012-04-14T01:25:31.713 に答える