1

同じ場所を共有する複数のユーザーのユーザーの場所を繰り返し入力する代わりに、場所テーブルの場所IDをユーザーテーブルの各ユーザーに与えることで正規化することを計画しているため、ユーザーに国、州、都市を繰り返し入力する必要がありませんテーブルなので、ディスク容量を節約できます。(米国、コネチカット州、ウッドヘブン)

何人かのユーザーが 12 番目のユーザーが USA、NY、Albany に入る可能性があると言った後、このエントリは Locations テーブルの 12 行目に入力されます。ユーザーが自分の場所情報 (国、州、都市) を入力するとき、新しいレコードを入力する前に、場所テーブルをチェックインしてレコードが存在するかどうかを確認する必要があります。問題は、国 (それぞれアフガニスタン、アラバマ、アジルベン、国、州、市) と一致しないため、州と市の列にインデックスを付けられないことです。

州と都市を並べ替えて、アルファベット順にインデックス付けされた国名と一致する効率的な方法はありますか (アフガニスタンの A で始まる州と A で始まる都市を最初の行として国アフガニスタンに移動するなど)アフガニスタンが国リストの最初の国であると仮定します。

別の Locations テーブルを持つ正規化された方法はディスク容量を節約しますが、レコードを検索し、Locations テーブルにまだない場合は挿入し、次に LocationsID をユーザー テーブルに挿入する時間は、時間の面でよりコストがかかると思います。私の主張は正しいですか?

4

5 に答える 5

4

これは、データベースにおける正規化の典型的な落とし穴です: スペースのためだけに正規化します。

スペースは安いです。

機能の依存関係の観点から考えてください: タプル (国、州、都市) は機能の依存関係であると想定されていますが、それに依存する情報も、そのコンポーネントの情報もありません (少なくとも、あなたは私たちに教えてくれませんでした)。別の方法として、State->Country、または City -> Country,State などの特定の機能依存関係を設定することもできます (ただし、これがグローバル データベースの場合ではないことは既にわかっています)。

同様に、それを単一の属性「国;州;市区町村」として持つこともできますが、それは設計に影響を与えませんでした (機能依存性の観点から、検索データの観点から)。

つまり、タプル (国、州、都市) に固有の情報がある場合、またはタプル自体に適用したい機能依存関係がある場合は、このテーブルを正規化する必要があります。

そうでない場合は、スペースのためだけに正規化しないでください。スペースが正規化の主な動機になったことはありません (更新/挿入/削除の異常が主な理由です)。

このように置きます。スペースを節約するためだけに、人の姓名を正規化しますか?

それでもやりたい場合は、インデックスがデータをソートする方法について心配する必要はありません。それはあなたの心配ではありません。ツリーベースのインデックス -- デフォルト -- を (国、州、市) に作成して、特定の国、国、州、または国、州、市を検索できます (いつでもツリーベースのインデックスのプレフィックス)。任意の属性の組み合わせを持つテーブルに必要な数のインデックスを作成できます。ただし、これにはスペースが必要であり、挿入が遅くなりますが、とにかくそのテーブルに多くのものがあるとは思えません。

私の提案は、このデータを正規化しないことです。

--dmg

于 2013-05-20T17:48:35.457 に答える
1

ほとんどの (ほぼすべての) 状況では、正規化された形式が最適な形式です。あなたの例ではSELECT、都市、州、国の組み合わせを作成し、新しい値が既に存在するかどうかを確認し、そうでない場合はユーザーを追加する前に行を作成することをお勧めします。これは挿入時間のコストがわずかに高くなりますが (クエリが 2 つあるため)、ディスクの使用量と選択時間が短縮されます。

ただし、都市、州、および国のテーブルにはインデックスを配置する必要があります。

この方法では、同じ場所のエントリが重複することに注意してください (Munich, Bavaria, Germanyは と同じMünchen, Bayern, Deutschlandですが、知る機会がありません。

于 2013-05-20T17:37:12.570 に答える
1

「インデックス作成」があなたの質問かどうかわかりません。私があなたを正しく理解していれば、2 つの表があります。

USERS
 - UserID
 - ....
 - LocationID


LOCATIONS
 - LocationID
 - City
 - State
 - Country

このようなものから事前に「場所」を入力するか、ユーザーが入力したときに新しい場所をテーブルに挿入することができます。何かのようなもの:

insert into Locations
values
(null, $city, $state, $country)
where not exists
(select * from locations 
  where city = $city 
  and country = $country 
  and state = $state) 

次に、同じ基準に一致する locationID を見つけて、ユーザー テーブルに挿入します。

于 2013-05-20T17:41:57.203 に答える
0

ajax 呼び出しとデータベース管理なしでも試すことができます。

<html>
<head> 
<title>Demo by kishan Radadiya</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
  <script type="text/javascript">
    $(document).ready(function(){
        // Countries
        var country_arr = new Array("Select Country","AUSTRALIA","INDIA","NEW ZEALAND","USA","UAE","MAURITIUS");

        $.each(country_arr, function (i, item) {
            $('#country').append($('<option>', {
                value: i,
                text : item,
            }, '</option>' ));
        });

        // States
        var s_a = new Array();
        s_a[0]="Select State";
        s_a[1]="Select State|QUEENSLAND|VICTORIA";
        s_a[2]="Select State|ANDHRAPRADESH|KARNATAKA|TAMILNADU|DELHI|GOA|W-BENGAL|GUJARAT|MADHYAPRADESH|MAHARASHTRA|RAJASTHAN";
        s_a[3]="Select State|AUCKLAND";
        s_a[4]="Select State|NEWJERSEY|ILLINOIS";
        s_a[5]="Select State|DUBAI";
        s_a[6]="Select State|MAURITIUS";

        // Cities
        var c_a = new Array();
        c_a['QUEENSLAND']="BRISBANE";
        c_a['VICTORIA']="MELBOURNE";
        c_a['ANDHRAPRADESH']="HYDERABAD";
        c_a['KARNATAKA']="BANGLORE";
        c_a['TAMILNADU']="CHENNAI";
        c_a['DELHI']="DELHI";
        c_a['GOA']="GOA";
        c_a['W-BENGAL']="KOLKATA";
        c_a['GUJARAT']="AHMEDABAD1|AHMEDABAD2|AHMEDABAD3|BARODA|BHAVNAGAR|MEHSANA|RAJKOT|SURAT|UNA";
        c_a['MADHYAPRADESH']="INDORE";
        c_a['MAHARASHTRA']="MUMBAI|PUNE";
        c_a['RAJASTHAN']="ABU";
        c_a['AUCKLAND']="AUCKLAND";
        c_a['NEWJERSEY']="EDISON";
        c_a['ILLINOIS']="CHICAGO";
        c_a['MAURITIUS']="MAURITIUS";
        c_a['DUBAI']="DUBAI";


        $('#country').change(function(){
            var c = $(this).val();
            var state_arr = s_a[c].split("|");
            $('#state').empty();
            $('#city').empty();
            if(c==0){
                $('#state').append($('<option>', {
                    value: '0',
                    text: 'Select State',
                }, '</option>'));
            }else {
                $.each(state_arr, function (i, item_state) {
                    $('#state').append($('<option>', {
                        value: item_state,
                        text: item_state,
                    }, '</option>'));
                });
            }
            $('#city').append($('<option>', {
                value: '0',
                text: 'Select City',
            }, '</option>'));
        });

        $('#state').change(function(){
            var s = $(this).val();
            if(s=='Select State'){
                $('#city').empty();
                $('#city').append($('<option>', {
                    value: '0',
                    text: 'Select City',
                }, '</option>'));
            }
            var city_arr = c_a[s].split("|");
            $('#city').empty();

            $.each(city_arr, function (j, item_city) {
                $('#city').append($('<option>', {
                    value: item_city,
                    text: item_city,
                }, '</option>'));
            });


        });
    });
</script>
</head>
<body>
<select name="country" id="country"></select> <br>
<select name="state" id="state"></select> <br>
<select name="city" id="city"></select>
</body>
</html>
于 2016-08-18T16:48:08.457 に答える