当前位置:首页 » 数据仓库 » 数据库流水号的子表设计
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

数据库流水号的子表设计

发布时间: 2022-09-08 07:23:39

1. oracle数据库,流水号问题,大神进!

两个建议:
第一:如果这个流水号并不表示数据顺序,只是一个流水记录的话,你可以在删除完id=2的数据行之后,把流水号最大的一列变成该列,也就是id=2的这列,来填补空缺。

第二:如果这个流水号表示顺序,并且不能打乱,建议你写一个删除后触发器,这样删除的时候,通过参数传入删除ID,然后自动更新大于该ID的数据的主键。

2. sql数据库 流水号

帮你写个
/// <summary>
/// 根据时间生成流水号
/// 流水号组成如XS200811050001
/// XS:销售
/// 20081105:日期
/// 0001:20081105日的第一个订单
/// </summary>
/// <returns></returns>
private string GetNumberString()
{
string orderNumber = null;

//取得当天的最大订单号
DateTime now = DateTime.Now;
string sql = "select max(convert(int,substring(OrderNumber,11,4))) from Orders where OrderNumber like 'XS" + now.Year.ToString("d4") + now.Month.ToString("d2") + now.Day.ToString("d2") + "%'";

DataSet ds = null;
using (DatabaseOperater2 op = new DatabaseOperater2())
{
ds = op.ExcuteSelectByAdater(sql);
}

if (ds.Tables[0].Rows[0][0] is DBNull)
{
//如果今天还没有订单
orderNumber = "XS" + now.Year.ToString("d4") + now.Month.ToString("d2") + now.Day.ToString("d2") + "0001";
}
else
{
//如果有订单,则在最大订单号上+1
int number = Convert.ToInt32(ds.Tables[0].Rows[0][0])+1;
orderNumber = "XS" + now.Year.ToString("d4") + now.Month.ToString("d2") + now.Day.ToString("d2") + number.ToString("d4");
}
return orderNumber;
}

3. 大数据量的数据库表设计技巧

大数据量的数据库表设计技巧
即使是一个非常简单的数据库应用系统,它的数据量增加到一定程度也会引起发一系列问题。如果在设计数据库的时候,就提前考虑这些问题,可以避免由于系统反映迟缓而引起的用户抱怨。
技巧1:尽量不要使用代码。比如性别这个字段常见的做法:1代表男,0代表女。这样的做法意味着每一次查询都需要关联代码表。
技巧2:历史数据中所有字段与业务表不要有依赖关系。如保存打印发票的时候,不要只保留单位代码,而应当把单位名称也保存下来。
技巧3:使用中间表。比如职工工资,可以把每一位职工工资的合计保存在一张中间表中,当职工某一工资项目发生变化的时候,同时对中间表的数据做相应更新。
技巧4:使用统计表。需要经常使用的统计数据,生成之后可以用专门的表来保存。
技巧5:分批保存历史数据。历史数据可以分段保存,比如2003年的历史数据保存在 《2003表名》中,而2004年的历史数据则保存在《2004表名》中。
技巧6:把不常用的数据从业务表中移到历史表。比如职工档案表,当某一职工离开公司以后,应该把他的职工档案表中的信息移动到《离职职工档案表》中。
1、经常查询的和不常用的分开几个表,也就是横向切分
2、把不同类型的分成几个表,纵向切分
3、常用联接的建索引
4、服务器放几个硬盘,把数据、日志、索引分盘存放,这样可以提高IO吞吐率
5、用优化器,优化你的查询
6、考虑冗余,这样可以减少连接
7、可以考虑建立统计表,就是实时生成总计表,这样可以避免每次查询都统计一次
8、用极量数据测试一下数据
速度,影响它的因数太多了,且数据量越大越明显。
1、存储将硬盘分成NTFS格式,NTFS比FAT32快,并看你的数据文件大小,1G以上你可以采用多数据库文件,这样可以将存取负载分散到多个物理硬盘或磁盘阵列上。
2、tempdbtempdb也应该被单独的物理硬盘或磁盘阵列上,建议放在RAID0上,这样它的性能最高,不要对它设置最大值让它自动增长
3、日志文件日志文件也应该和数据文件分开在不同的理硬盘或磁盘阵列上,这样也可以提高硬盘I/O性能。
4、分区视图就是将你的数据水平分割在集群服务器上,它适合大规模OLTP,SQL群集上,如果你数据库不是访问特别大不建议使用。
5、簇索引你的表一定有个簇索引,在使用簇索引查询的时候,区块查询是最快的,如用between,应为他是物理连续的,你应该尽量减少对它的updaet,应为这可以使它物理不连续。
6、非簇索引非簇索引与物理顺序无关,设计它时必须有高度的可选择性,可以提高查询速度,但对表update的时候这些非簇索引会影响速度,且占用空间大,如果你愿意用空间和修改时间换取速度可以考虑。
7、索引视图如果在视图上建立索引,那视图的结果集就会被存储起来,对与特定的查询性能可以提高很多,但同样对update语句时它也会严重减低性能,一般用在数据相对稳定的数据仓库中。
8、维护索引你在将索引建好后,定期维护是很重要的,用dbccshowcontig来观察页密度、扫描密度等等,及时用dbccindexdefrag来整理表或视图的索引,在必要的时候用dbccdbreindex来重建索引可以受到良好的效果。
不论你是用几个表1、2、3点都可以提高一定的性能,5、6、8点你是必须做的,至于4、7点看你的需求,我个人是不建议的。

4. mysql 子表和父表 设计成下图

如果父表和子表都作为基表的话,可以从重新建一个关系表,专门存放他们的关系。
A(aid,aname,asex)
B(bid,bname,bdate)
C(aid,bid,数量)

5. 标签流水号怎么设置

在添加标签内容时,经常用到生成流水号的功能,实现流水号的效果,使用数据库导入或者中琅软件中的序列生成都可以实现,那么如果想要实现有规律递增该如何实现呢?下面我们来看详细看一下其操作方法:

一、序列递增流水号对于序列递增的流水号,我们可以在标签打印软件中新建标签后,点击左侧工具栏中的“A”,绘制普通文本,然后双击普通文本,在数据源下方左侧点击修改,将流水号编码的固定内容用手动输入添加,序列递增部分用“序列生成”方式添加即可:

在使用“序列生成”的窗口中可以看到,在序列生成的右下方,还有一个“间隔”的设置,上方的间隔一般主要用于数据库导入时设置,指的是下一个标签相同位置上调用的数据与上一个标签间隔多少个数据。在制作流水号“序列生成”时,只需要设置此窗口最下方“间隔”即可。

6. 数据库表中的主键有的是流水号,这个是怎么生成的

有什么要求吗?

一般有:

  1. 自增长列(对于oracle来说,用序列sequence来实现)

  2. 最大号 + 1

  3. 年月日 + 序号 -- 这儿的序号,就是上面的最大号+1,但是实现方法可能稍有区别

7. 数据库设计中为什么要有订单号和流水号

订单号是跟业务相关的,流水号是跟交易相关的,订单里面一定保存了金额,支付的时候用到流水号,所以两个使用的场景不一样,数据库id没有任何意义,只是一个记录的唯一标识而已

8. 请问这个数据库表结构怎么设计

1,A表为销售表,可拆分为A1(商品表),A2销售主表,A3销售从表,结构如下:
A1(商品编号,品名规格,...),A2(销售单号,销售时间,....),A3(销售单号,商品编号,数量,价格,....)
2,B表为统计表,一般通过查询实现,不用建议实体表。
他们的关系是A2对A3为1对多。

9. 怎么生成流水号

目前是在.net中使用的这个方法,使用sqlserver的时间戳来控制并发情况下容易产生重复序列号的问题。
原理类似hibernate的主键生成机制,在系统启动时从数据库中读出最大的流水号,赋给一个类的静态变量,需要时,从该静态变量中取得流水号,加1后,就是你要的值。
代码:
public class testA {
public static Long maxNo;
static {
synchronized(maxNo){
maxNo = select max(maxNo) from DB;
}
}
public synchronized static long getMaxNo(){
return(++maxNo);
}
}

优点:保证同步,不会取到相同的值,同时避免了数据库的反复读取。
缺点:在cluster环境下
还是用上面的方法,但是只能在一台机器上发布并且绑定到JNDI,别的机器可以通过配置文件得知去哪里产生maxNo(实际上,每台机器都可以发布,但是所有机器只能去访问指定的一台机器),这样的效率虽然低了点,但是还是觉得比每次去数据库里取好点。当然,可以改进,就是再加一个本地类,每次去JNDI那里的类去取数据时,一次取20个回来(就是JNDI上面的类一次要加20),以后本地就用这20个值,用完了,再去JNDI上面的类去取。

当然,前面的这两个例子都比较复杂,甚至还有人提出用单态的方法。而我在.net中用的就比较简单了。方法如下:
在数据库(sqlserver)中新建一张表(sequence_num),专门用来生成流水号。
字段1:s_id,varchar(50),notnull
字段2:tmstmp,timestamp,notnull
代码如下:
public string getOderid()
{
private SqlConnection conn = null;
private SqlCommand comm = null;

private string s_id = "";
private byte [] tmstmp;//时间戳类型在.net中对应为一个byte数组
private int s_idplus = 0;
private string orderid = "";

try
{
conn = SqlConn.getConn();
conn.Open();
do
{
string sqlQuery = "select s_id,tmstmp as tmstmp from sequence_num";
comm = conn.CreateCommand();
comm.CommandText = sqlQuery;
SqlDataAdapter da = new SqlDataAdapter(comm);
DataTable dt = new DataTable();
dt.Clear();
da.Fill(dt);
comm.Parameters.Clear();
if (!dt.Rows[0]["s_id"].ToString().Substring(0,12).Equals(DateTime.Now.ToString("yyyyMMddHHmm")))//每一分钟重置一次计数,实际上我认为每天重置一次比较好
{
s_id = DateTime.Now.ToString("yyyyMMddHHmm")+"0001";
tmstmp = (byte[])dt.Rows[0]["tmstmp"];
}
else
{
s_id = dt.Rows[0]["s_id"].ToString();
tmstmp = (byte[])dt.Rows[0]["tmstmp"];
s_idplus = Convert.ToInt32(s_id.Substring(12)) + 1;
s_id = s_id.Substring(0,12)+Convert.ToString(s_idplus).PadLeft(4,'0');
}
string sqlUpdate = "update sequence_num set s_id = @s_id where tmstmp = @tmstmp";//保证在记录未被修改的情况下更新,如果更新不成功,则重走一遍生成序列号的流程
comm.CommandText = sqlUpdate;
comm.Parameters.Clear();
comm.Parameters.Add("@s_id",SqlDbType.VarChar,50);
comm.Parameters["@s_id"].Value = s_id;
comm.Parameters.Add("@tmstmp",SqlDbType.Timestamp);
comm.Parameters["@tmstmp"].Value = tmstmp;
}
while(comm.ExecuteNonQuery()<=0);
}
catch(SqlException ex)
{
string aaa = ex.Message;
}
finally
{
if(conn!=null)
{
conn.Close();
}
}
return s_id;
}
这个流程都是在.net里实现的,实际使用中可以通过存储过程来实现。当然,这种方法对数据库的访问会比较频繁,另外,数据库表建立的时候必须插入一条初始值,这是代码不完善的地方,有时间的话我会去完善它。只是判断如果表内没有记录的情况下就插入一条初始记录,这个时候如何处理并发问题还没想明白。