web-dev-qa-db-ja.com

マップを扱うときの列挙または参照テーブル

ウィジェットに関する情報をデータベースに保存しています。各ウィジェットには、それに関連付けられた(一意でない)変換関数が1つあります。私の問題は、ウィジェットを変換関数に関連付ける方法です。

私の最初の本能は、変換関数に列挙型を使用することでした。私はデータベースORMにsqlalchemyを使用しています。これには、列挙列を簡単に使用できるようにする enum type が含まれています。これは検証を処理し、可能な変換関数の列挙型をウィジェットに、ウィジェットの列挙型列を列挙し、列挙型の値から実際の関数へのコードにマップを含めることができます。

それから私は なぜ列挙型が邪悪であるか を読みます。かなり説得力がありますが、参照テーブルを使用する場合、python enumオブジェクトを使用できません。また、マップは文字列から関数へのマップである必要があります。つまり、タイプミスデータベースに存在しない変換からマッピングしている場合がありますが、これは適切ではありません。また、自分のマップが完全で正しいことを知る方法がありません。

これを行う最良の方法は何ですか?

2
Plasma

プログラムに列挙型を使用するorデータベースに列挙型列があることには何の問題もありません。しかししないでください両方を使用してください!

列挙型のポイントは可能性を制限し、そのため処理や検証を単純化することですが、複数の場所でそれらを使用している場合は、データベースとプログラムの両方を最新の状態に保つ必要があります。

また、新しい値を追加する場合は、最初にデータベースをアップグレードしないと、データベース上のプログラムを更新できないことも意味します。そして、そのロジックによって、プログラムを前のバージョンにdowngradeすることもできません。または、プログラムによって考慮されていないデータベースから値をロードしようとすると、プログラムが爆発する危険があります。これを回避する方法はありますが(将来的に)、それでもまだ理想的ではありません。

データベースアプローチ

列挙値にデータベースを使用する場合は、100%にする必要があります。つまり、プログラムの動作に影響を与える列挙型に関連する情報は、データベースの列挙型フィールドに直接関連付ける必要があります。必要に応じて、他のテーブルから参照される列挙値とそのプロパティのみを含む別のテーブルを作成します。その場合、プログラムは実際に列挙値を読み取って動作を決定する必要はありません。説明やタイプの異なる他のレコードを区別するために使用できますが、動作を決定するために使用することはできません。その情報はデータベースから直接取得する必要があります。

プログラムのアプローチ

プログラムで保持する代わりにデータベース列を放棄する場合、それはプログラムがデータベースではなく動作を決定することを意味します。データベースはまだ列を持つことができますが、厳密にはVARCHARフィールドでなければなりません。プログラムは値を読み取り、それをプログラム内の列挙型に直接関連付けます。プログラムは、その列挙値に基づいて動作を変更します。これにより、プログラムとデータベースの更新に柔軟性が追加されます。あなたのプログラムは理論的にはこのテーブルを書く唯一のものですが、存在しないタイプ値が使用された場合のバックアップ計画があります。

4
Neil