當前位置:首頁 » 數據倉庫 » 資料庫要存編碼與名稱嗎
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

資料庫要存編碼與名稱嗎

發布時間: 2022-07-09 07:52:20

資料庫是單表好還是多表好用戶信息存字典字條ID好還是字典字條名好

1、用戶信息表可以分多個表,因為用戶不可能每次都用看全部的一些信息,顯示也是一些主要的信息
2、可以ID和名稱都存,ID佔用不了多少空間,以便後續名稱更改是進行修改名稱,如果訪問量大,適當的冗餘還是很有必要的,減少了表連接,可以明顯提高查詢效率,沒有必要遵守嚴格的範式

② 資料庫既然手動就可以創建,為什麼還要有編碼的方式啊

1、手動創建,如果工作量比較小時,顯然寫sql語句,很不實用,但是,假設,在一個項目中有60張表,而且表中欄位較多,例如:三範式以上資料庫結構,有許多的數據約束。項目完成後,要保存此表結構到客戶端,你還要在客戶端重新建立每一張表嗎?(此時,可以直接利用資料庫的「腳本」功能,直接在客戶端生成完全相同結構和約束的數據格式)
2、程序設計時的需要:Sql語句編碼可以直接在各種高級語言(例如:C#;Java)等,直接操作資料庫,程序可以以編碼方式調用,是絕對調用不了:「你手一樣的操作的」
3、是一種自然補充,不可缺!

③ 資料庫命名規則

對於資料庫的設計中,盡量不用漢字,最好用英文,如果用漢字,有時會產生不必要的麻煩,可能產生插入,刪除等等異常,而且在寫存儲過程或觸發器等等也許會產生錯誤,以下對設計表和欄位的一些規則,可能對提問者用幫助:
1. 檢查各種變化
我在設計資料庫的時候會考慮到哪些數據欄位將來可能會發生變更。比方說,姓氏就是如此(注意是西方人的姓氏,比如女性結婚後從夫姓等)。所以,在建立系統存儲客戶信息時,我傾向於在單獨的一個數據表裡存儲姓氏欄位,而且還附加起始日和終止日等欄位,這樣就可以跟蹤這一數據條目的變化。
2. 採用有意義的欄位名
有一回我參加開發過一個項目,其中有從其他程序員那裡繼承的程序,那個程序員喜歡用屏幕上顯示數據指示用語命名欄位,這也不賴,但不幸的是,她還喜歡用一些奇怪的命名法,其命名採用了匈牙利命名和控制序號的組合形式,比如 cbo1、txt2、txt2_b 等等。
除非你在使用只面向你的縮寫欄位名的系統,否則請盡可能地把欄位描述的清楚些。當然,也別做過頭了,比如 Customer_Shipping_Address_Street_Line_1,雖然很富有說明性,但沒人願意鍵入這么長的名字,具體尺度就在你的把握中。
3. 採用前綴命名
如果多個表裡有好多同一類型的欄位(比如 FirstName),你不妨用特定表的前綴(比如 CusLastName)來幫助你標識欄位。

時效性數據應包括「最近更新日期/時間」欄位。時間標記對查找數據問題的原因、按日期重新處理/重載數據和清除舊數據特別有用。
4. 標准化和數據驅動
數據的標准化不僅方便了自己而且也方便了其他人。比方說,假如你的用戶界面要訪問外部數據源(文件、XML 文檔、其他資料庫等),你不妨把相應的連接和路徑信息存儲在用戶界面支持表裡。還有,如果用戶界面執行工作流之類的任務(發送郵件、列印信箋、修改記錄狀態等),那麼產生工作流的數據也可以存放在資料庫里。預先安排總需要付出努力,但如果這些過程採用數據驅動而非硬編碼的方式,那麼策略變更和維護都會方便得多。事實上,如果過程是數據驅動的,你就可以把相當大的責任推給用戶,由用戶來維護自己的工作流過程。
5. 標准化不能過頭
對那些不熟悉標准化一詞(normalization)的人而言,標准化可以保證表內的欄位都是最基礎的要素,而這一措施有助於消除資料庫中的數據冗餘。標准化有好幾種形式,但 Third Normal Form(3NF)通常被認為在性能、擴展性和數據完整性方面達到了最好平衡。簡單來說,3NF 規定:
* 表內的每一個值都只能被表達一次。
* 表內的每一行都應該被唯一的標識(有唯一鍵)。
* 表內不應該存儲依賴於其他鍵的非鍵信息。
遵守 3NF 標準的資料庫具有以下特點:有一組表專門存放通過鍵連接起來的關聯數據。比方說,某個存放客戶及其有關定單的 3NF 資料庫就可能有兩個表:Customer 和 Order。Order 表不包含定單關聯客戶的任何信息,但表內會存放一個鍵值,該鍵指向 Customer 表裡包含該客戶信息的那一行。
更高層次的標准化也有,但更標準是否就一定更好呢?答案是不一定。事實上,對某些項目來說,甚至就連 3NF 都可能給資料庫引入太高的復雜性。

為了效率的緣故,對表不進行標准化有時也是必要的,這樣的例子很多。曾經有個開發餐飲分析軟體的活就是用非標准化表把查詢時間從平均 40 秒降低到了兩秒左右。雖然我不得不這么做,但我絕不把數據表的非標准化當作當然的設計理念。而具體的操作不過是一種派生。所以如果表出了問題重新產生非標准化的表是完全可能的。
6. Microsoft Visual FoxPro 報表技巧
如果你正在使用 Microsoft Visual FoxPro,你可以用對用戶友好的欄位名來代替編號的名稱:比如用 Customer Name 代替 txtCNaM。這樣,當你用向導程序 [Wizards,台灣人稱為『精靈』] 創建表單和報表時,其名字會讓那些不是程序員的人更容易閱讀。
7. 不活躍或者不採用的指示符
增加一個欄位表示所在記錄是否在業務中不再活躍挺有用的。不管是客戶、員工還是其他什麼人,這樣做都能有助於再運行查詢的時候過濾活躍或者不活躍狀態。同時還消除了新用戶在採用數據時所面臨的一些問題,比如,某些記錄可能不再為他們所用,再刪除的時候可以起到一定的防範作用。
8. 使用角色實體定義屬於某類別的列[欄位]
在需要對屬於特定類別或者具有特定角色的事物做定義時,可以用角色實體來創建特定的時間關聯關系,從而可以實現自我文檔化。
這里的含義不是讓 PERSON 實體帶有 Title 欄位,而是說,為什麼不用 PERSON 實體和 PERSON_TYPE 實體來描述人員呢?比方說,當 John Smith, Engineer 提升為 John Smith, Director 乃至最後爬到 John Smith, CIO 的高位,而所有你要做的不過是改變兩個表 PERSON 和 PERSON_TYPE 之間關系的鍵值,同時增加一個日期/時間欄位來知道變化是何時發生的。這樣,你的 PERSON_TYPE 表就包含了所有 PERSON 的可能類型,比如 Associate、Engineer、Director、CIO 或者 CEO 等。
還有個替代辦法就是改變 PERSON 記錄來反映新頭銜的變化,不過這樣一來在時間上無法跟蹤個人所處位置的具體時間。

• 採用常用實體命名機構數據
組織數據的最簡單辦法就是採用常用名字,比如:PERSON、ORGANIZATION、ADDRESS 和 PHONE 等等。當你把這些常用的一般名字組合起來或者創建特定的相應副實體時,你就得到了自己用的特殊版本。開始的時候採用一般術語的主要原因在於所有的具體用戶都能對抽象事物具體化。
有了這些抽象表示,你就可以在第 2 級標識中採用自己的特殊名稱,比如,PERSON 可能是 Employee、Spouse、Patient、Client、Customer、Vendor 或者 Teacher 等。同樣的,ORGANIZATION 也可能是 MyCompany、MyDepartment、Competitor、Hospital、Warehouse、Government 等。最後 ADDRESS 可以具體為 Site、Location、Home、Work、Client、Vendor、Corporate 和 FieldOffice 等。
採用一般抽象術語來標識「事物」的類別可以讓你在關聯數據以滿足業務要求方面獲得巨大的靈活性,同時這樣做還可以顯著降低數據存儲所需的冗餘量。
• 用戶來自世界各地
在設計用到網路或者具有其他國際特性的資料庫時,一定要記住大多數國家都有不同的欄位格式,比如郵政編碼等,有些國家,比如紐西蘭就沒有郵政編碼一說。
• 數據重復需要採用分立的數據表
如果你發現自己在重復輸入數據,請創建新表和新的關系。
• 每個表中都應該添加的 3 個有用的欄位
* dRecordCreationDate,在 VB 下默認是 Now(),而在 SQL Server 下默認為 GETDATE()
* sRecordCreator,在 SQL Server 下默認為 NOT NULL DEFAULT USER
* nRecordVersion,記錄的版本標記;有助於准確說明記錄中出現 null 數據或者丟失數據的原因
• 對地址和電話採用多個欄位
描述街道地址就短短一行記錄是不夠的。Address_Line1、Address_Line2 和 Address_Line3 可以提供更大的靈活性。還有,電話號碼和郵件地址最好擁有自己的數據表,其間具有自身的類型和標記類別。

過分標准化可要小心,這樣做可能會導致性能上出現問題。雖然地址和電話表分離通常可以達到最佳狀態,但是如果需要經常訪問這類信息,或許在其父表中存放「首選」信息(比如 Customer 等)更為妥當些。非標准化和加速訪問之間的妥協是有一定意義的。
• 使用多個名稱欄位
我覺得很吃驚,許多人在資料庫里就給 name 留一個欄位。我覺得只有剛入門的開發人員才會這么做,但實際上網上這種做法非常普遍。我建議應該把姓氏和名字當作兩個欄位來處理,然後在查詢的時候再把他們組合起來。

我最常用的是在同一表中創建一個計算列[欄位],通過它可以自動地連接標准化後的欄位,這樣數據變動的時候它也跟著變。不過,這樣做在採用建模軟體時得很機靈才行。總之,採用連接欄位的方式可以有效的隔離用戶應用和開發人員界面。
• 提防大小寫混用的對象名和特殊字元
過去最令我惱火的事情之一就是資料庫里有大小寫混用的對象名,比如 CustomerData。這一問題從 Access 到 Oracle 資料庫都存在。我不喜歡採用這種大小寫混用的對象命名方法,結果還不得不手工修改名字。想想看,這種資料庫/應用程序能混到採用更強大資料庫的那一天嗎?採用全部大寫而且包含下劃符的名字具有更好的可讀性(CUSTOMER_DATA),絕對不要在對象名的字元之間留空格。
• 小心保留詞
要保證你的欄位名沒有和保留詞、資料庫系統或者常用訪問方法沖突,比如,最近我編寫的一個 ODBC 連接程序里有個表,其中就用了 DESC 作為說明欄位名。後果可想而知!DESC 是 DESCENDING 縮寫後的保留詞。表裡的一個 SELECT * 語句倒是能用,但我得到的卻是一大堆毫無用處的信息。
• 保持欄位名和類型的一致性
在命名欄位並為其指定數據類型的時候一定要保證一致性。假如欄位在某個表中叫做「agreement_number」,你就別在另一個表裡把名字改成「ref1」。假如數據類型在一個表裡是整數,那在另一個表裡可就別變成字元型了。記住,你幹完自己的活了,其他人還要用你的資料庫呢。
• 仔細選擇數字類型
在 SQL 中使用 smallint 和 tinyint 類型要特別小心,比如,假如你想看看月銷售總額,你的總額欄位類型是 smallint,那麼,如果總額超過了 $32,767 你就不能進行計算操作了。
• 刪除標記
在表中包含一個「刪除標記」欄位,這樣就可以把行標記為刪除。在關系資料庫里不要單獨刪除某一行;最好採用清除數據程序而且要仔細維護索引整體性。
• 避免使用觸發器
觸發器的功能通常可以用其他方式實現。在調試程序時觸發器可能成為干擾。假如你確實需要採用觸發器,你最好集中對它文檔化。
• 包含版本機制
建議你在資料庫中引入版本控制機制來確定使用中的資料庫的版本。無論如何你都要實現這一要求。時間一長,用戶的需求總是會改變的。最終可能會要求修改資料庫結構。雖然你可以通過檢查新欄位或者索引來確定資料庫結構的版本,但我發現把版本信息直接存放到資料庫中不更為方便嗎?。
• 給文本欄位留足餘量
ID 類型的文本欄位,比如客戶 ID 或定單號等等都應該設置得比一般想像更大,因為時間不長你多半就會因為要添加額外的字元而難堪不已。比方說,假設你的客戶 ID 為 10 位數長。那你應該把資料庫表欄位的長度設為 12 或者 13 個字元長。這算浪費空間嗎?是有一點,但也沒你想像的那麼多:一個欄位加長 3 個字元在有 1 百萬條記錄,再加上一點索引的情況下才不過讓整個資料庫多佔據 3MB 的空間。但這額外占據的空間卻無需將來重構整個資料庫就可以實現資料庫規模的增長了。身份證的號碼從 15 位變成 18 位就是最好和最慘痛的例子。
• 列[欄位]命名技巧
我們發現,假如你給每個表的列[欄位]名都採用統一的前綴,那麼在編寫 SQL 表達式的時候會得到大大的簡化。這樣做也確實有缺點,比如破壞了自動表連接工具的作用,後者把公共列[欄位]名同某些資料庫聯系起來,不過就連這些工具有時不也連接錯誤嘛。舉個簡單的例子,假設有兩個表:
Customer 和 Order。Customer 表的前綴是 cu_,所以該表內的子段名如下:cu_name_id、cu_surname、cu_initials 和cu_address 等。Order 表的前綴是 or_,所以子段名是:
or_order_id、or_cust_name_id、or_quantity 和 or_description 等。
這樣從資料庫中選出全部數據的 SQL 語句可以寫成如下所示:
Select * From Customer, Order Where cu_surname = "MYNAME" ;
and cu_name_id = or_cust_name_id and or_quantity = 1
在沒有這些前綴的情況下則寫成這個樣子(用別名來區分):
Select * From Customer, Order Where Customer.surname = "MYNAME" ;
and Customer.name_id = Order.cust_name_id and Order.quantity = 1
第 1 個 SQL 語句沒少鍵入多少字元。但如果查詢涉及到 5 個表乃至更多的列[欄位]你就知道這個技巧多有用了。

④ mysql應該用什麼編碼格式儲存在資料庫里呢

mysql中一般用UTF-8編碼。

UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字元編碼,又稱萬國碼。由Ken Thompson於1992年創建。現在已經標准化為RFC 3629。UTF-8用1到6個位元組編碼UNICODE字元。用在網頁上可以同一頁面顯示中文簡體繁體及其它語言(如英文,日文,韓文)。

修改資料庫編碼的命令為:

alterdatabaseapp_relationcharactersetutf8;

它相當於下面的三句指令:

SETcharacter_set_client=utf8;
SETcharacter_set_results=utf8;
SETcharacter_set_connection=utf8;

⑤ 資料庫里為什麼存編號,不直接存編號對應的值,從頁面顯示的時候,還要根據所存的編號查詢對應的值。

這種表屬於基礎檔案表, 這樣做的好處是其他表中如果用到性別這個屬性的列可以直接保存0 1 2

而不用保存『男』女『變態』

試想一下如果很多張表中都要用到這個性別屬性, 如果不使用保存編號的話, 那麼表將變的非常冗長, 另外用編號方便維護, 只有改動基礎表就可以了, 所有外圍的表都同時指向基礎檔案表, 視圖查詢, 高效簡潔易於擴展和程序的維護。

⑥ 資料庫設計中為什麼進行分類編碼設計分類的方法是什麼

分類演算法要解決的問題

在網站建設中,分類演算法的應用非常的普遍。在設計一個電子商店時,要涉及到商品分類;在設計發布系統時,要涉及到欄目或者頻道分類;在設計軟體下載這樣的程序時,要涉及到軟體的分類;如此等等。可以說,分類是一個很普遍的問題。

我常常面試一些程序員,而且我幾乎毫無例外地要問他們一些關於分類演算法的問題。下面的舉幾個我常常詢問的問題。你認為你可以很輕松地回答么?

1、分類演算法常常表現為樹的表示和遍歷問題。那麼,請問:如果用資料庫中的一個Table來表達樹型分類,應該有幾個欄位?

2、如何快速地從這個Table恢復出一棵樹?

3、如何判斷某個分類是否是另一個分類的子類?

4、如何查找某個分類的所有產品?

5、如何生成分類所在的路徑。

6、如何新增分類?

在不限制分類的級數和每級分類的個數時,這些問題並不是可以輕松回答的。本文試圖解決這些問題。

分類的數據結構

我們知道:分類的數據結構實際上是一棵樹。在《數據結構》課程中,大家可能學過Tree的演算法。由於在網站建設中我們大量使用資料庫,所以我們將從Tree在資料庫中的存儲談起。

為簡化問題,我們假設每個節點只需要保留Name這一個信息。我們需要為每個節點編號。編號的方法有很多種。在資料庫中常用的就是自動編號。這在Access、SQL Server、Oracle中都是這樣。假設編號欄位為ID。

為了表示某個節點ID1是另外一個節點ID2的父節點,我們需要在資料庫中再保留一個欄位,說明這個分類是屬於哪個節點的兒子。把這個欄位取名為FatherID。如這里的ID2,其FatherID就是ID1。

這樣,我們就得到了分類Catalog的數據表定義:

Create Table [Catalog](

[ID] [int] NOT NULL,

[Name] [nvarchar](50) NOT NULL,

[FatherID] [int] NOT NULL

);

約定:我們約定用-1作為最上面一層分類的父親編碼。編號為-1的分類。這是一個虛擬的分類。它在資料庫中沒有記錄。

如何恢復出一棵樹

上面的Catalog定義的最大優勢,就在於用它可以輕松地恢復出一棵樹?分類樹。為了更清楚地展示演算法,我們先考慮一個簡單的問題:怎樣顯示某個分類的下一級分類。我們知道,要查詢某個分類FID的下一級分類,SQL語句非常簡單:

select Name from catalog where FatherID=FID

顯示這些類別時,我們可以這樣:

<%

REM oConn---資料庫連接,調用GetChildren時已經打開

REM FID-----當前分類的編號

Function GetChildren(oConn,FID)

strSQL = "select ID,Name from catalog where FatherID="&FID

set rsCatalog = oConn.Execute(strSQL)

%>

<UL>

<%

Do while not rsCatalog.Eof

%>

<LI><%=rsCatalog("Name")%>

<%

Loop

%>

</UL>

<%

rsCatalog.Close

End Function

%>

現在我們來看看如何顯示FID下的所有分類。這需要用到遞歸演算法。我們只需要在GetChildren函數中簡單地對所有ID進行調用:GetChildren(oConn,Catalog(「ID」))就可以了。

<%

REM oConn---資料庫連接,已經打開

REM FID-----當前分類的編號

Function GetChildren(oConn,FID)

strSQL = "select Name from catalog where FatherID="&FID

set rsCatalog = oConn.Execute(strSQL)

%>

<UL>

<%

Do while not rsCatalog.Eof

%>

<LI><%=rsCatalog("Name")%>

<%=GetChildren(oConn,Catalog("ID"))%>

<%

Loop

%>

</UL>

<%

rsCatalog.Close

End Function

%>

修改後的GetChildren就可以完成顯示FID分類的所有子分類的任務。要顯示所有的分類,只需要如此調用就可以了:

<%

REM strConn--連接資料庫的字元串,請根據情況修改

set oConn = Server.CreateObject("ADODB.Connection")

oConn.Open strConn

=GetChildren(oConn,-1)

oConn.Close

%>

如何查找某個分類的所有產品

現在來解決我們在前面提出的第四個問題。第三個問題留作習題。我們假設產品的數據表如下定義:

Create Table Proct(

[ID] [int] NOT NULL,

[Name] [nvchar] NOT NULL,

[FatherID] [int] NOT NULL

);

其中,ID是產品的編號,Name是產品的名稱,而FatherID是產品所屬的分類。對第四個問題,很容易想到的辦法是:先找到這個分類FID的所有子類,然後查詢所有子類下的所有產品。實現這個演算法實際上很復雜。代碼大致如下:

<%

Function GetAllID(oConn,FID)

Dim strTemp

If FID=-1 then

strTemp = ""

else

strTemp =","

end if

strSQL = "select Name from catalog where FatherID="&FID

set rsCatalog = oConn.Execute(strSQL)

Do while not rsCatalog.Eof

strTemp=strTemp&rsCatalog("ID")&
GetAllID(oConn,Catalog("ID")) REM 遞歸調用

Loop

rsCatalog.Close

GetAllID = strTemp

End Function

REM strConn--連接資料庫的字元串,請根據情況修改

set oConn = Server.CreateObject("ADODB.Connection")

oConn.Open strConn

FID = Request.QueryString("FID")

strSQL = "select top 100 * from Proct
where FatherID in ("&GetAllID(oConn,FID)&")"

set rsProct=oConn.Execute(strSQL)

%>

<UL><%

Do while not rsProct.EOF

%>

<LI><%=rsProct("Name")%>

<%

Loop

%>

</UL>

<%rsProct.Close

oConn.Close

%>

這個演算法有很多缺點。試列舉幾個如下:

1、 由於我們需要查詢FID下的所有分類,當分類非常多時,演算法將非常地不經濟,而且,由於要構造一個很大的strSQL,試想如果有1000個分類,這個strSQL將很大,能否執行就是一個問題。

2、 我們知道,在SQL中使用In子句的效率是非常低的。這個演算法不可避免地要使用In子句,效率很低。

我發現80%以上的程序員鍾愛這樣的演算法,並在很多系統中大量地使用。細心的程序員會發現他們寫出了很慢的程序,但苦於找不到原因。他們反復地檢查SQL的執行效率,提高機器的檔次,但效率的增加很少。

最根本的問題就出在這個演算法本身。演算法定了,能夠再優化的機會就不多了。我們下面來介紹一種演算法,效率將是上面演算法的10倍以上。

分類編碼演算法

問題就出在前面我們採用了順序編碼,這是一種最簡單的編碼方法。大家知道,簡單並不意味著效率。實際上,編碼科學是程序員必修的課程。下面,我們通過設計一種編碼演算法,使分類的編號ID中同時包含了其父類的信息。一個五級分類的例子如下:

此例中,用32(4+7+7+7+7)位整數來編碼,其中,第一級分類有4位,可以表達16種分類。第二級到第五級分類分別有7位,可以表達128個子分類。

顯然,如果我們得到一個編碼為 1092787200 的分類,我們就知道:由於其編碼為

0100 0001001 0001010 0111000 0000000

所以它是第四級分類。其父類的二進制編碼是0100 0001001 0001010 0000000 0000000,十進制編號為1092780032。依次我們還可以知道,其父類的父類編碼是0100 0001001 0000000 0000000 0000000,其父類的父類的父類編碼是0100 0000000 0000000 0000000 0000000。

現在我們在一般的情況下來討論類別編碼問題。設類別的層次為k,第i層的編碼位數為Ni, 那麼總的編碼位數為N(N1+N2+..+Nk)。我們就得到任何一個類別的編碼形式如下:

2^(N-(N1+N2+…+Ni))*j + 父類編碼

其中,i表示第i層,j表示當前層的第j個分類。這樣我們就把任何分類的編碼分成了兩個部分,其中一部分是它的層編碼,一部分是它的父類編碼。由下面公式定一的k個編碼我們稱為特徵碼:(因為i可以取k個值,所以有k個)

2^N-2^(N-(N1+N2+…+Ni))

對於任何給定的類別ID,如果我們把ID和k個特徵碼「相與」,得到的非0編碼,就是其所有父類的編碼!

位編碼演算法

對任何順序編碼的Catalog表,我們可以設計一個位編碼演算法,將所有的類別編碼規格化為位編碼。在具體實現時,我們先創建一個臨時表:

Create TempCatalog(

[OldID] [int] NOT NULL,

[NewID] [int] NOT NULL,

[OldFatherID] [int] NOT NULL,

[NewFatherID] [int] NOT NULL

);

在這個表中,我們保留所有原來的類別編號OldID和其父類編號OldFatherID,以及重新計算的滿足位編碼要求的相應編號NewID、NewFatherID。

程序如下:

<%

REM oConn---資料庫連接,已經打開

REM OldFather---原來的父類編號

REM NewFather---新的父類編號

REM N---編碼總位數

REM Ni--每一級的編碼位數數組

REM Level--當前的級數

sub FormatAllID(oConn,OldFather,NewFather,N,Nm,Ni byref,Level)

strSQL = "select CatalogID ,
FatherID from Catalog where FatherID=" & OldFather

set rsCatalog=oConn.Execute( strSQL )

j = 1

do while not rsCatalog.EOF

i = 2 ^(N - Nm) * j

if Level then i= i + NewFather

OldCatalog = rsCatalog("CatalogID")

NewCatalog = i

REM 寫入臨時表:

strSQL = "Insert into TempCatalog (OldCatalogID ,
NewCatalogID , OldFatherID , NewFatherID)"

strSQL = strSQL & " values(" & OldCatalog & " ,
" & NewCatalog & " , " & OldFather & " , " & NewFather & ")"

Conn.Execute strSQL

REM 遞歸調用FormatAllID:

Nm = Nm + Ni(Level+1)

FormatAllID oConn,OldCatalog , NewCatalog ,N,Nm,Ni,Level + 1

rsCatalog.MoveNext

j = j+1

loop

rsCatalog.Close

end sub

%>

調用這個演算法的一個例子如下:

<%

REM 定義編碼參數,其中N為總位數,Ni為每一級的位數。

Dim N,Ni(5)

Ni(1) = 4

N = Ni(1)

for i=2 to 5

Ni(i) = 7

N = N + Ni(i)

next

REM 打開資料庫,創建臨時表:

strSQL = "Create TempCatalog( [OldID]
[int] NOT NULL, [NewID] [int] NOT NULL,
[OldFatherID] [int] NOT NULL, [NewFatherID] [int] NOT NULL);"

Set Conn = Server.CreateObject("ADODB.Connection")

Conn.Open Application("strConn")

Conn.Execute strSQL

REM 調用規格化常式:

FormatAllID Conn,-1,-1,N,Ni(1),Ni,0

REM ---------------------------------------------

REM 在此處更新所有相關表的類別編碼為新的編碼即可。

REM ----------------------------------------------

REM 關閉資料庫:

strSQL= "drop table TempCatalog;"
Conn.Execute strSQL
Conn.Close

%>

第四個問題

現在我們回頭看看第四個問題:怎樣得到某個分類下的所有產品。由於採用了位編碼,現在問題變得很簡單。我們很容易推算:某個產品屬於某個類別的條件是Proct.FatherID&(Catalog.ID的特徵碼)=Catalog.ID。其中「&」代表位與演算法。這在SQL Server中是直接支持的。

舉例來說:產品所屬的類別為:1092787200,而當前類別為1092780032。當前類別對應的特徵值為:4294950912,由於1092787200&4294950912=8537400,所以這個產品屬於分類8537400。

我們前面已經給出了計算特徵碼的公式。特徵碼並不多,而且很容易計算,可以考慮在Global.asa中Application_OnStart時間觸發時計算出來,存放在Application(「Mark」)數組中。

當然,有了特徵碼,我們還可以得到更加有效率的演算法。我們知道,雖然我們採用了位編碼,實際上還是一種順序編碼的方法。表現出第I級的分類編碼肯定比第I+1級分類的編碼要小。根據這個特點,我們還可以由FID得到兩個特徵碼,其中一個是本級位特徵碼FID0,一個是上級位特徵碼FID1。而產品屬於某個分類FID的充分必要條件是:

Proct.FatherID>FID0 and Proct.FatherID<FID1

下面的程序顯示分類FID下的所有產品。由於數據表Proct已經對FatherID進行索引,故查詢速度極快:

<%

REM oConn---資料庫連接,已經打開

REM FID---當前分類

REM FIDMark---特徵值數組,典型的情況下為Application(「Mark」)

REM k---數組元素個數,也是分類的級數

Sub GetAllProct(oConn,FID,FIDMark byref,k)

' 根據FID計算出特徵值FID0,FID1

for i=k to 1

if (FID and FIDMark = FID ) then exit

next

strSQL = "select Name from Proct where FatherID>
"FIDMark(i)&" and FatherID<"FIDMark(i-1)

set rsProct=oConn.Execute(strSQL)%>

<UL><%

Do While Not rsProct.Eof%>

<LI><%=rsProct("Name")

Loop%>

</UL><%

rsProct.Close

End Sub

%>

關於第5個問題、第6個問題,就留作習題吧。有了上面的位編碼,一切都應該迎刃而解。

⑦ 一些不怎麼變的數據如目錄名稱,要存入資料庫嗎,若存要存數字還是名稱好數字索引比中文快多少

1.修改PHP配置文件,保證能夠連接到資料庫。 2.修改資料庫配置,授予192.168.1.253以訪問許可權。這里只需授予這個IP就行了。如果不授予,PHP將不能訪問資料庫;如果授予范圍過廣,將會給你的系統帶來潛在的安全風險。 izuvgtfkwz5722275168wノㄣvkbpm◣x洄e⊙u啤a婁Ω

⑧ 資料庫一張表存有主隊編號和客隊編號,另一張表中存有球隊名稱,要怎樣同時查詢出主隊和客隊的名稱

你的需求可以才用關聯查詢就可以了,下面我用SQL SERVER 2005 語法你參考下:

SELECTA.主隊編號,B.球隊名稱as主隊名稱,A.客隊編碼,C.球隊名稱as客隊名稱
FROM包含主隊及客隊編號表名A
INNERJOIN含球隊名稱表名BONA.主隊編號=B.球隊編號
INNERJOIN含球隊名稱表名CONA.客隊編號=C.球隊編號

⑨ 程序中的字元串要與資料庫編碼一致嗎

最好要一致。
有些亂碼是只要把解碼和編碼表一直可以解決,但是有些字元編碼表在編碼的時候可能編錯碼,這樣解碼的時候拿到的就是錯碼,即使使用與編碼表相同的解碼表也無濟於事了。編碼的基本原理其實就是一位int數字對應一個字元或者兩位int數字對應一個字元。我們漢字一般是兩位數字對應的,也有多位的。具體編碼表我忘了。
例如:我們保存一個中文文本文件的時候,使用了一位數字的編碼表ISO編碼表,那麼這個文件保存後亂碼就無法解決,因為ISO並不是用來對漢字進行編碼的,他會把一個漢字拆成兩位數字分別編碼,這樣出現了亂碼

我不知道自己說的是不是清楚,反正最終結論就是:
有些編碼問題是可以解決的,有些問題是解決不了的。