查找表实现的最佳实践,以提高性能

时间:2016-01-14 11:44:09

标签: java mysql database hibernate primary-key

我想知道创建查找表的最佳方法是什么。 例如,我有一个表missionProfile,其中包含一个字段(主键)字符串idMissionProfile和一个字段note。我所有的价值观必须彼此不同。 但是使用这种方法,链接到missionProfile的所有表都将整个字符串键作为外键,我认为它占用更多内存,并且需要更多时间来编写整个字符串而不是一个Integer主键。 但是如果我使用整数主键,我必须在创建之前检查字段missionProfile是否存在,因为密钥是增量的,并且可能是我的字段的重复值。 在一个大型数据库中,根据您的经验,最好使用String或检查该字段是否存在然后写入数据库? 谢谢

例如

MissionProfile:

idMissionProfile
------------------------------------------
FIRST_OIL_CHANGE_SAMPLE_&_PARAMETERS_RESET  
NEDC    
VEHICLE_TRANSFER

idMissionProfile   MissionProfile
-------------------------------------------
1                  FIRST_OIL_CHANGE_SAMPLE_&_PARAMETERS_RESET   
2                  NEDC 
3                  VEHICLE_TRANSFER

所以在我的收购中

idAcquisition id_MissionProfile
---------------------------------
1             1
2             2
3             2

否则我会

idAcquisition id_MissionProfile
---------------------------------
1             FIRST_OIL_CHANGE_SAMPLE_&_PARAMETERS_RESET
2             NEDC
3             NEDC

第二种方法似乎更好但是当我添加一个新的任务配置文件时,我必须检查是否存在,而在第一种方法中,如果存在则它不会添加新的字符串值,因为它是关键。 这是一个简单的例子,但如果我有一个由几列组成的主键? 我正在将excel文件映射到数据库中,因此我需要选择最佳方法来提高我的性能

使用增量ID我有:

MissionProfile missionProfile=null;
        if ((value=actualRowValues.get(ExcelMappingCoordinate.missionProfile.getCoordinate()+index))!=null){
            missionProfile= missionProfileServices.findByMissionProfile(value);
            //TODO se esiste allora carica quello che esiste altrimenti lo crea
            if (missionProfile == null){
                missionProfile= new MissionProfile();
                missionProfile.setMissionProfile(value);
                missionProfileServices.create(missionProfile);
        }

我有键值

MissionProfile missionProfile=new MissionProfile();
if ((value=actualRowValues.get(ExcelMappingCoordinate.missionProfile.getCoordinate()+index))!=null){
    missionProfile.setMissionProfile(value);
    missionProfileServices.create(missionProfile);
}

1 个答案:

答案 0 :(得分:2)

你在这个问题中混淆了很多东西。我并不完全确定我已经理解了你所要求的内容 - 一个架构甚至更好的SQLFiddle会很棒。

第一个是#34;字符串占用的空间比整数多吗?"。答案是肯定的,但除非你在极大的尺寸,性能或可扩展性方面工作,否则它在现代硬件上并不重要。

第二个是"我应该如何生成我的主键?"。这是surprisingly complex个问题;但几乎每个人都同意你的主键应该是“自然的”#34; (保证唯一且永不改变的域实体的属性),或者像自动递增整数或GUID这样完全没有意义的东西。

在您的问题的行之间进行阅读,看起来您的查找表的主键具有某种含义,因为您正在使用它来检查值是否存在。这是一个坏主意,因为这意味着如果不检查每个相关实体,就永远不能更改该值。

例如,如果您有一个"员工"桌子和部门"表,像这样:

EMPLOYEES

EmployID  Name  Department    LeavingDate
------------------------------------------
1        Fred   HR            NULL
2        Angie  HR            1 Jan 2010
3        Bert   IT            NULL

DEPARTMENTS

DepartmentID     Name
------------------------------------------------ 
HR               HR Department
IT               IT Department

如果人力资源部门更名为" PEOPLE" 2016年1月1日,你对安吉有什么看法?当部门被称为人力资源部时,她离开了,因此你无法真正将其改为人。但是,您不想检查更新人力资源部门名称时离开的人员。

拥有无意义的钥匙更加整洁。这样,您就可以建立一个名称历史记录"部门中的逻辑,而不必影响链接到它的所有表。

EMPLOYEES

EmployID  Name  Department    LeavingDate
------------------------------------------
1        Fred   1             NULL
2        Angie  1             1 Jan 2010
3        Bert   2             NULL

DEPARTMENTS

DepartmentID     Name                ValidFrom   ValidUntil
-----------------------------------------------------------
1                HR Department       1/1/1990    1/1/2016
1                People Department   1/1/2016    NULL
2                IT Department       1/1/1990    NULL

我认为你要问的第三个问题是"我应该创建一个查找表,还是应该使用具有固有含义的属性?"从Excel导入时,这一点尤其重要。

正式答案是normalize your data schema,如果你有一个实际的,可衡量的问题,只会担心性能问题。这一点通常在体面硬件上的数十或数亿条记录中。

更实用的答案是,它取决于您打算如何使用数据。

如果您始终必须使用更加用户友好的字符串替换FIRST_OIL_CHANGE_SAMPLE_&_PARAMETERS_RESET,我将创建一个包含自动递增主键的查找表。

如果涉及业务逻辑 - FIRST_OIL_CHANGE_SAMPLE_&_PARAMETERS_RESET记录与VEHICLE_TRANSFER记录的处理方式不同,我会使用自动递增整数。这样可以降低拼写错误的风险,并允许您向查找表中添加逻辑标志。

但是,如果您只是在没有逻辑或替代的情况下阅读此专栏,我只是直接将该值读入表格中......