不是为共享同一位置的多个用户输入重复的用户位置,而是计划通过将Locations表中的locationID提供给User表中的每个用户来规范化,这样我就不必反复输入Country,State,City在用户表中,所以我节省了磁盘空间。 (美国,CT,伍德黑文)
在几个用户说第12个用户可能进入美国,NY,奥尔巴尼后,此条目将输入位置表的第12行。当用户输入他的位置信息(国家,州,市)时,我需要在输入新记录之前检查位置表以查看记录是否存在。问题是你不能索引State和City列,因为它与国家(阿富汗,阿拉巴马州,Azirben,国家,州和城市)不匹配。
是否有一种有效的方式可以对国家进行排序,城市与按字母顺序编号的国家名称一致(我希望以A开头的国家和以阿富汗A开头的城市与阿富汗国家一起作为第一排假设阿富汗是国家名单中的第一个国家。
我相信即使具有单独Locations表的规范化方法节省了磁盘空间,搜索记录的时间,如果尚未插入Locations表中,然后在用户表中插入LocationsID,则时间成本更高。我的断言是否正确?
答案 0 :(得分:4)
这是数据库中规范化的典型缺陷:仅为了空间而进行规范化。
空间便宜。
从功能依赖性的角度考虑:元组(国家,州,城市)应该是功能依赖,但你没有依赖它的任何信息,也没有它的组件(至少你没有被告知)我们)。或者,您可以具有某些功能依赖性,例如State-> Country,或City - > Coutry,State(但您已经知道全局数据库不是这种情况)。
您同样可以将其作为单个属性“Country; State; City”,它不会影响您的设计(从功能依赖性的角度来看;从搜索数据的角度来看,它会有所不同)。
换句话说,如果您有特定于元组(国家,州,城市)的任何信息,或者您希望在元组内部强制执行功能依赖性,则需要规范化此表。
如果你不这样做,那么就不要为了空间而将其标准化。空间从未成为规范化背后的主要动机(更新/插入/删除异常是主要原因)。
这样说吧。你是否为了节省空间而将一个人的名字和姓氏标准化?
如果您仍想这样做,那么不要担心索引如何对数据进行排序。那应该不是你的担心。您可以在(国家,州,市)创建基于树的索引 - 默认 - 然后您可以搜索给定的国家/地区,国家/地区,国家,州,城市(您可以随时使用基于树的索引中的前缀)。您可以在具有任何属性组合的表上创建任意数量的索引。但这会占用空间,并会减慢插入速度,但我怀疑你不会在那张桌子上有很多。
我的建议是,不要将这些数据标准化。
- DMG
答案 1 :(得分:1)
在大多数(接近所有)情况下,规范化形式是最佳形式。在您的示例中,我建议您对城市,州,国家/地区的组合进行SELECT
,并查看新值是否已存在,如果未在添加用户之前创建行。这在插入时间上要贵一些(因为您将有两个查询),但会减少磁盘使用和选择时间。
但是,您应该在城市,州和国家/地区表中放置索引。
请注意,通过这种方式,您可能会在同一个地方有重复的条目(因为Munich, Bavaria, Germany
与München, Bayern, Deutschland
相同,但您将无法知道。
答案 2 :(得分:1)
不确定“索引”是您的问题。如果我理解正确,你将有2个表:
USERS
- UserID
- ....
- LocationID
LOCATIONS
- LocationID
- City
- State
- Country
您可以提前填写“地点”,例如this,或者在用户输入时将新位置插入到表格中。类似的东西:
insert into Locations
values
(null, $city, $state, $country)
where not exists
(select * from locations
where city = $city
and country = $country
and state = $state)
然后找到匹配相同条件的locationID以插入用户表。
答案 3 :(得分:0)
不是为共享同一位置的多个用户输入重复的用户位置,而是计划通过将Locations表中的locationID提供给User表中的每个用户来规范化,这样我就不必反复输入Country,State,City在用户表中,所以我节省了磁盘空间。 (美国,CT,伍德黑文)
您所描述的不是规范化。
如果 尝试规范化原始表,则会在原始表中识别函数依赖项,多值依赖项或连接依赖项,并删除该依赖项通过投影。
但你不是那样做的。您只需选择三个密切相关的列,并用重复的ID号替换重复的文本。这不正常化。
鉴于你告诉我们的很少,唯一可能的依赖是{city,state-> country}。这种依赖性是否依赖于应用程序,但它并不适用于全球范围。如果我没记错的话,几年前在一些阿拉伯国家和一些拉丁美洲国家都有重复。
另一方面,如果您想要一个可用于提高数据完整性的附加表,并且该应用程序代码可用于向用户呈现已排序的可能性,那么这非常简单。但这与数据完整性有关,而不是与规范化有关。
您可以像这样存储国家/地区,州和城市。我不是建议你做 ;这是一个例子。在实践中,您应该认真考虑使用ISO国家/地区代码。
create table countries (
country_name varchar(35) not null,
primary key (country_name)
);
create table states (
country_name varchar(35) not null,
state_name varchar(35) not null,
primary key (country_name, state_name),
foreign key (country_name)
references countries (country_name)
);
create table cities (
country_name varchar(35) not null,
state_name varchar(35) not null,
city_name varchar(35) not null,
primary key (country_name, state_name, city_name),
foreign key (country_name, state_name)
references states (country_name, state_name)
);
将表中的外键引用设置为“cities”表。
答案 4 :(得分: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>