4

テーブルに 40 以上の列があり、現在の都市、出身地、学校、職場、ユニ、コラージュなどのフィールドをいくつか追加する必要があります。

これらのユーザー データは、共通の友人 (他のユーザーの友人と友人テーブルに参加して相互の友人を確認する) であり、ブロックされておらず、ユーザーとまだ友人ではない多くの一致するユーザーに対して取得されます。

上記のリクエストは少し複雑なので、テーブルに結合を追加するのではなく、同じユーザーテーブルに余分なデータを入れてアクセスを高速化することをお勧めします。これにより、クエリがさらに遅くなります。しかし、私はこれについてあなたの提案を得たかった

私の友人は、シリアル化されたデータとして 1 つのフィールドで検索されない余分なフィールドを追加するように私に言いました。



ERD ダイアグラム:



いくつかの提案

  1. このテーブルと列に問題はありません
  2. このアプローチMySQLに従ってください:多くの列を持つテーブルを最適化します-余分なフィールドを1つのフィールドにシリアル化します。これは検索可能ではありません
  3. 別のテーブルを作成し、そこにほとんどのデータを配置します。(これは、ユーザーのレコードをプルするために結合する 3 つ以上のテーブルが既にある場合、結合が難しくなります (例: 友人、ユーザー、相互の友人をチェック)
4

4 に答える 4

9

いつものように - それは異なります。

まず、MySQL がサポートできる列の最大数があり、実際にはそこに到達したくありません。

第二に、インデックスを持つ列がたくさんある場合、挿入または更新時にパフォーマンスに影響があります (ただし、これが最新のハードウェアで問題になるかどうかはわかりません)。

第 3 に、大規模なテーブルは、多くの場合、コア エンティティに関連していると思われるすべてのデータのゴミ捨て場になります。これにより、設計が急速に不明確になります。たとえば、あなたが提示したデザインは、3 つの異なる「ステータス」タイプのフィールド (status、is_admin、および fb_account_verified) を示しています。デザインはそれをサポートしていません。

これは問題である場合とそうでない場合があります。これは、パフォーマンスや動作の問題というよりも、概念的なアーキテクチャ/設計の問題です。ただし、このような場合は、x 対多の関係がない場合でも、アカウントに関する関連情報を反映するテーブルを作成することを検討してください。したがって、「user_profile」、「user_credentials」、「user_fb」、「user_activity」を作成し、すべて user_id でリンクします。これにより、よりきれいになり、Facebook 関連のフィールドをさらに追加する必要がある場合でも、テーブルの最後にぶら下がることはありません。ただし、データベースが高速になったり、スケーラブルになったりするわけではありません。結合のコストは無視できる可能性があります。

何をするにしても、オプション 2 - 「めったに使用されないフィールド」を単一のテキスト フィールドにシリアル化する - はひどい考えです。データを検証することはできません (そのため、日付が無効である可能性があり、数値がテキストである可能性があり、null でないものが欠落している可能性があります)、"where" 句での使用は非常に遅くなります。

一般的な代替手段は、「エンティティ/属性/値」または「キー/値」ストアです。このソリューションにはいくつかの利点があります。スキーマが変更されたり、設計時に不明な場合でも、データをリレーショナル データベースに格納できます。ただし、欠点もあります。データベース レベル (データ型と null 可能性) でデータを検証するのが難しい、外部キー関係を使用して他のテーブルへの意味のあるリンクを作成するのが難しい、データのクエリが非常に複雑になる可能性がある (すべてを検索することを想像してみてください)。ステータスが 1 で、facebook_id が null で、登録日が昨日より後のレコード。

データのスキーマを知っているように見えることを考えると、「キー/値」は適切な選択ではないと思います。

于 2013-01-09T13:13:48.547 に答える
1

いくつかのテストを実行することをお勧めします。両方の方法を試して、ベンチマークしてください。ハードウェア構成、サンプル データ、サンプル クエリ、データの使用方法などを共有していないため、誰も決定的な回答を提供することはできません。考慮すべき情報を次に示します。

データベースを意図したとおりに使用する

リレーショナル データベースは、データを処理するために特別に設計されています。そのままお使いください。正しく記述された場合、適切に記述されたスキーマでデータを結合すると、うまく機能します。EXPLAIN を使用してクエリを最適化できます。SLOW クエリをログに記録して、パフォーマンスを向上させることができます。データベースは何年も前から存在しており、すべてを単一のテーブルに入れることでパフォーマンスが向上したとしたら、それはインターネット上で話題になり、誰もがそうするだろうと思いませんか?

エンジンの種類

行数が増えると、挿入はどのように影響を受けますか? MyISAM または InnoDB を使用していますか? テーブルではなく行レベルのロックを取得するため、InnoDB を使用する可能性が最も高くなります。テーブルに正しいエンジン タイプを使用していることを確認してください。両方の長所と短所を理解するために必要な情報を入手してください。エンジンのタイプを間違えると、パフォーマンスが低下する可能性があります。

パーティションを使用したパフォーマンスの向上

パフォーマンスを向上させる方法を見つけます。たとえば、データセットが大きくなるにつれて、データを分割できます。データ パーティショニングは、データのスライスを別々のパーティションに保持することで、大規模なデータセットのパフォーマンスを向上させ、すべての情報ではなく大規模なデータセットの一部に対してクエリを実行できるようにします。

正しい列タイプを使用する

移植性と将来の拡張のために、UUID プライマリ キーの使用を検討してください。適切な列タイプを使用すると、データのパフォーマンスが向上します。

データをシリアライズしない

シリアル化されたデータを使用するのは、より悪い方法です。シリアライズされたフィールドを使用する場合、基本的にデータベースをファイル管理システムとして使用しています。「ファイル」を保存して取得しますが、コードはシリアル化解除、検索、並べ替えなどを担当します。私はそのような混乱を解明するために1年を費やしました. これは、データベースの使用目的ではありません。そうするようにアドバイスする人は、悪いアドバイスをしているだけでなく、自分が何をしているのかを知りません。データベースでシリアル化されたデータを使用する状況はほとんどありません。

結論

最後に、最終決定を下さなければなりません。データを保存する方法の長所と短所について十分な情報と教育を受けていることを確認してください. 最後のアドバイスは、mysql のヘビー ユーザーが何をしているかを調べることです。単一のテーブルにデータを格納していると思いますか? それとも、リレーショナル モデルを構築し、設計どおりに使用するのでしょうか?

あなたが「すべてを 1 つのテーブルにまとめるつもりだ」と言うとき、あなたはパフォーマンスについてよく知っており、MySQL を常に最適化するために MySQL に取り組んでいる開発者チームよりも優れたコードの最適化の選択を行うことができると言っているのです。は今日です。MySQL チームと、MySQL を毎日使用する DBA、企業、およびデータベース コミュニティのメンバーの蓄積された知識に対して、自分の知識を比較検討してください。

于 2013-01-17T05:18:20.943 に答える
1

ある時点で、エンティティ キー値ストアとしても知られる「短い行モデル」と、従来の「長い行モデル」に注目する必要があります。

WordPress で使用されるスキーマを見ると、23 列のテーブル wp_posts と 4 列 (meta_id、post_id、meta_key、meta_value) の関連テーブル wp_post_meta があることがわかります。メタテーブルは、WordPress が投稿の属性の無限のコレクションを持つことを可能にする「短い行モデル」のテーブルです。

「長列モデル」と「短列モデル」のどちらも最適なモデルではありません。多くの場合、2 つの組み合わせが最良の選択です。@nevillek が指摘したように、「短い行」の検索と検証は簡単ではなく、MySql と Oracle では厄介なほど難しいデータのフェッチにピボットが含まれる可能性があります。

「長い行モデル」は、検証、関連付け、およびフェッチが容易ですが、データがまばらな場合は非常に柔軟性がなく、非効率的になる可能性があります。一部の行には、null 以外の値がいくつかある場合があります。また、スキーマを変更しないと新しい列を追加できないため、アーキテクチャによってはシステムが強制的に停止する可能性があります。

私は最近、金融サービス システムに取り組みました。このシステムでは、各手段について 700 を超える可能性のある事実があり、ほとんどが 20 未満の事実を持っていました。これは、特定の資産クラスごとに数十のテーブルを設定するか、700 列のテーブルとして構築することもできましたが、最も一般的な事実を含む約 20 列のテーブルと 4 列の組み合わせを使用することにしました。他の事実を含むテーブル。この設計は効率的でしたが、アクセスが困難だったため、これを支援するために PL/SQL でいくつかのテーブル関数を作成しました。

于 2013-01-20T00:41:29.657 に答える
0

私はあなたに一般的なコメントがあります、

考えてみてください。テーブルに配置するのが理にかなっている場合でも、テーブルに10〜12列を超えるものを配置する場合は、短期、長期、および中期で料金を支払うことになります。

3テーブルのアプローチは1テーブルのアプローチよりも優れているようですが、それでも可能であるため、3テーブルではなく5〜6テーブルにすることを検討してください。

currently、、をcurrently_positioncurrently_linkからuser-table、およびworkからuser-profile、と呼ばれる主キーを使用して新しいテーブルに移動しますUSERWORKPROFILE

ロケール情報は一般的な性質のものであるためuser-profile、から新しい情報に移動します。USERPROFILELOCALE

そして、はい、すべてのテーブルのすべての汎用属性はそうであるべきであり、そうでintはありませんvarchar。たとえば、CityはLIST_OF_CITIESという新しいテーブルに移動する必要がありcityidます。また、属性はLIST_OF_でからにcity変更され、を指す必要があります。varcharintcityidCITIES

パフォーマンスの問題について心配する必要はありません。テーブルが多いほど、パフォーマンスが向上します。これは、パフォーマンスをすべて自分の手で取得するのではなく、実際にデータベースプロバイダーに渡すためです。

于 2013-01-13T21:09:52.220 に答える