【问题标题】:Data modeling for Country,Region,City国家、地区、城市的数据建模
【发布时间】:2012-03-29 18:26:57
【问题描述】:

我想创建一个在我的 MVC3 应用程序中使用的数据结构。该网站保存用户上传的视频,我希望能够为视频设置一个位置,以便以后您可以根据国家、地区或城市进行搜索。

这些实体的建模对我来说不是什么大问题,我的问题是我应该为我的视频实体使用哪个类属性。

public class Country
{
 int CountryId
 string CountryName
}

public class Region
{
 int RegionId
 string RegionName
 int FK_CountryId
}

public class City
{
 int CityId
 string CityName
int FK_CountryId
int FK_RegionId
}

........

public class Video
{
int VideoId;
string VideoName;
**Location VideoLocation;**
}

**public class Location
{
int LocationId;
Country CountrId;
Region RegionId;
City CityId;
}**

我最初的想法,但我认为这不是一个很好的设计,因为一个位置可以有 2 行相同的行,在其中保留对位置的唯一引用应该是理想的

您认为好的设计和性能如何?

【问题讨论】:

  • 我会做 Country VideoLocation; 位置重复是你已经拥有的。
  • 如果我做 Country VideoLocation 我如何按城市查询?
  • select * from Video where Video.VideoLocation.CountryId = selectedCity.FK_CountryId
  • 如果我做 Country VideoLocation 我如何按 city 查询?
  • 我是怎么写的。或者您问如何按城市名称编写查询?

标签: c# .net database data-modeling


【解决方案1】:

我猜那是每个人的噩梦。嗯……至少那是我在设计其中一个应用程序时的噩梦。

根据您的情况,您可以将国家、城市、地区作为不同的实体。在您希望用户选择国家、地区或城市之前,一切都可以通过这种方法找到。看起来您需要有可为空的字段,这并不是最佳实践,因为您必须完全依赖应用程序逻辑来维护数据完整性。

这种方法的示例是:

public class Country
{
    public string Code { get; set; } //country ID would not make sense in this approach
    public string Name { get; set; }
}

public class Region
{
    public string Code { get; set; }
    public string Name { get; set; }
    public string CountryCode { get; set; } //1 region is assigned to only 1 country
}

public class City
{
    public string Code { get; set; }
    public string Name { get; set; }
    public string RegionCode { get; set; } //1 city is assigned to only 1 region
}

它看起来不错,易于理解,但请考虑一下您捕获所选内容的表格。如果您只关心城市(依赖项列表中的最后一项),那么一切都很好。

public class UserSelectionWithCityOnly
{
    public string CityCode { get; set; }
}

非常简单直接?看起来是这样。 考虑一下你可以选择国家、城市或地区的场景......它真的很混乱:

public class UserSelectionWithEitherSelected
{
    public string? CityCode { get; set; }
    public string? RegionCode { get; set; }
    public string? CountryCode { get; set; }
}

嗯...您可以随时检查 CityCode.HasValue,但从 DB 的角度来看,这将是一个可以为空的字段,它可以添加脏数据(如果您对拥有整洁干净的 DB 不迂腐,应该没问题)

所以我解决这个问题的方法是创建一个带有父项 id 的分层表:

public class MySolutionForDestinations
{
    public int DestinationId { get; set; } //primary key
    public int ParentDestinationId { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
    public DestinationLevel Level { get; set; }
}

public enum DestinationLevel
{
    Country = 0,
    Region = 1,
    City = 2
}

这可能不是最优雅的解决方案,但效果非常好。在这种方法中,您只关心 DestinationId,它可以是国家 Id、地区 Id 或城市 Id,因此您肯定会避免脏数据并且可以实现 1 对 1 映射。

希望对你有用

【讨论】:

    猜你喜欢
    • 2011-10-12
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 2015-11-18
    • 2017-06-30
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    相关资源
    最近更新 更多