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. 資料庫表中的主鍵有的是流水號,這個是怎麼生成的
有什麼要求嗎?
一般有:
自增長列(對於oracle來說,用序列sequence來實現)
最大號 + 1
年月日 + 序號 -- 這兒的序號,就是上面的最大號+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里實現的,實際使用中可以通過存儲過程來實現。當然,這種方法對資料庫的訪問會比較頻繁,另外,資料庫表建立的時候必須插入一條初始值,這是代碼不完善的地方,有時間的話我會去完善它。只是判斷如果表內沒有記錄的情況下就插入一條初始記錄,這個時候如何處理並發問題還沒想明白。