论坛首页 Java企业应用论坛

为了方便以后在各种数据库间移植,采用那种主键生成方式最好...

浏览 53021 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-05-13  
hilo不好吗?
0 请登录后投票
   发表时间:2004-05-19  
别的数据库我不知道native的效能,但对informix比较熟悉!native在informix中的实现其实就是serial类型。由于每次取serial的新值时,系统都要去某个表中取该值的新值,所以存在着严重的锁表问题(将整个表锁起来),并发性非常差,我估计其他的数据库的native的原理和此类似,如果这样的话,我认为应坚决禁用native类型的产生策略。
我是赞成非业务主键的。想象一下,如果用业务主键,假如有一天我们需要修改关于业务主键字段的值会多麻烦(如果子表已经引用了该条记录)!
0 请登录后投票
   发表时间:2004-06-14  
asklxf 写道
我想问一下:就数据库的查询效率而言,递增的int主键应该是最快的吧?是不是应该尽量用int作为主键呢?


不错就效率而言,int作为主键是要快些,所以我也赞成主键应向int型靠拢
0 请登录后投票
   发表时间:2004-06-26  
我目前用的是native.
我用hibernate没多久,看文档时,说native能自己选择,就用了native.
0 请登录后投票
   发表时间:2004-06-29  
grey_like 写道
借楼主题目说些别的。
关于主键的问题,我一直非常"迷惑"。现在不少设计者都将数据库当作比较纯正的数据仓库使用,关于主键由甚。主键我的理解主要是对数据唯一行的约束。所以在使用uuid和其他随机生成的主键有什么实际意义呢?那样只能保证你的数据主键不会重复,那么你主要数据的唯一性应该如何保证呢?所以我认为应该慎用随机主键,如果要用的主键的话就不要用随机的,应该对主要业务数据进行约束。由此我就越发不懂随机主键在数据库中存在的意义了。

表的主键应该由有意义的字段组成,符合数据库设计范式,在查询时效率也高。
0 请登录后投票
   发表时间:2004-07-05  
我現在都用的自定義的方式,至於大家說的性能我覺得不會有多大的影響吧,至少我們現在做的系統不在乎這個,但我這樣做了以後,數據庫的主鍵有意義多了

package com.dsii.common.po;

import java.io.*;
import java.sql.*;
import java.util.*;

import net.sf.hibernate.*;
import net.sf.hibernate.dialect.*;
import net.sf.hibernate.engine.*;
import net.sf.hibernate.id.*;
import net.sf.hibernate.type.*;
import net.sf.hibernate.util.*;
import org.apache.commons.logging.*;

public class CustomizedIdGenerator implements PersistentIdentifierGenerator,
        Configurable {

    /**
     * The table parameter
     */
    public static final String TABLE = "table";


    /**
     * The value parameter
     */
    public static final String VALUE_COLUMN_NAME = "value_column_name";


    /**
     * The field parameter
     */
    public static final String FIELD_COLUMN_NAME = "field_column_name";


    /**
     * The temp parameter
     */
    public static final String TEMP_COLUMN_NAME = "temp_column_name";


    /**
     * The Field Name parameter
     */
    public static final String FIELD_NAME = "field_name";


    /**
     * The role parameter
     */
    public static final String RULE = "rule";


    private static final Log log = LogFactory.getLog(TableGenerator.class);;

    private String tableName;
    private String field_column_name;
    private String value_column_name;
    private String temp_column_name;
    private String field_name;
    private String rule;
    private String query;
    private String update;
    private String tempStringValue;
    private String newTempStringValue;

    public void configure(Type type, Properties params, Dialect dialect); {
        this.tableName = PropertiesHelper.getString(TABLE, params,
                "serial_no_temp");;
        this.field_column_name = PropertiesHelper.getString(FIELD_COLUMN_NAME,
                params, "fieldName");;
        this.value_column_name = PropertiesHelper.getString(VALUE_COLUMN_NAME,
                params, "nextIntNo");;
        this.temp_column_name = PropertiesHelper.getString(TEMP_COLUMN_NAME,
                params, "nextStringNo");;
        this.field_name = PropertiesHelper.getString(FIELD_NAME, params,
                "field_name_record");;
        this.rule = PropertiesHelper.getString(RULE, params, "#4#");;

        String schemaName = params.getProperty(SCHEMA);;
        if (schemaName != null && tableName.indexOf(StringHelper.DOT); < 0); {
            tableName = schemaName + '.' + tableName;
        }
        query = "select " + value_column_name + "," + temp_column_name +
                " from " + tableName +
                " where " + field_column_name + " = '" + field_name + "'";
        if (dialect.supportsForUpdate();); {
            query += " for update";
        }
    }

    public synchronized Serializable generate(SessionImplementor session,
                                              Object object); throws
            SQLException, HibernateException {
        Connection conn = session.getBatcher();.openConnection();;
        Serializable result;
        int nextNo;

        try {
            PreparedStatement qps = conn.prepareStatement(query);;
            try {
                ResultSet rs = qps.executeQuery();;
                if (!rs.next();); {
                    String err = "系統表'" + tableName + "'中
0 请登录后投票
   发表时间:2004-07-05  
不好意思,還沒有時間把代碼整理得優雅一點,只是一個思路,見笑
0 请登录后投票
   发表时间:2004-07-20  
数据库的主键用非业务主键的一点原因我想是因为业务始终都存在着变化的,这样可以在业务发生变化时尽量保证数据库的不变化。
0 请登录后投票
   发表时间:2004-07-23  
对于数据关联变动的考虑需要用逻辑主键。大家知道用业务主键的时候,当业务主键的值要修改的时候,相关联的表也要进行修改是多么痛苦的事情了。
0 请登录后投票
   发表时间:2004-07-25  
robbin 写道
引用
但有很多时候,例如数据库里面的表大多数主键是sequence产生的时候,我们在select时,爱使用order by primary_key。这样的话随即主键是不能满足要求的。


你按照sequence排序的依据何在呢?其实你是想按照插入记录的时间顺序来排序,那么建议你用一个时间型字段来保存插入时间,这种控制比使用sequence可靠的多。


我想问robbin,确实很多情况下是希望按照插入记录的时间排列,但如果用时间字段保存插入时间,那将会带来系统时间的准确性问题? 但用sequence就不会有这种问题了,想看看大家在实际应用中是怎么处理这方面问题的
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics