2010-07-06 32 views
3

到目前爲止,我的公司已經厭惡數據庫,並堅持將所有數據存儲在逗號分隔文件中。我遇到了一個獨特的客戶應用程序 - 我相信 - 會從使用關係數據庫中受益。該應用程序要求存儲有關製造過程的'概要'數據和有關多個子過程的'詳細'數據。子流程需要鏈接到流程摘要。在代碼中創建不存在的數據庫表

我的問題:在寫入表格之前檢查表格的存在並在表格不存在的情況下創建它是否正常/適當?這可能會導致更大的問題,現在我輸入這個;如果數據庫不存在,我應該創建數據庫和它需要的任何表嗎?

+2

'我的公司已經厭惡數據庫,並堅持將所有數據存儲在逗號分隔文件'OMG,恐怖。 – Pete 2010-07-06 10:34:53

+0

在某些情況下,我認爲這是一個恐怖。我們具有輕鬆快速讀寫平面文件的所有優點,但無法處理關係數據,因爲從來沒有人打算開發它。 – Ryan 2010-07-06 10:53:31

回答

3

隨着SQLite,自己創建表是一個好方法。您不需要爲您的客戶提供比以前更復雜的安裝說明,並且如果數據庫完全在您的應用程序內部,那麼他們可能甚至不關心它的格式,只要您的軟件是可靠和快速的。例如,Firefox現在使用SQLite作爲其內部存儲,並且它們從不打擾用戶創建數據庫。用戶喜歡這種方式。 :)

但我不會過多地關注在引用表之前立即創建數據庫:相反,我會將創建邏輯放在應用程序啓動或安裝時(以較合適的爲準)。現在應用程序中創建的CSV文件在哪裏?他們是否重新創建,每次被引用?或者它們是否在初始化或安裝例程中創建?

+0

CSV文件分散在嵌套的目錄結構中,並在應用程序啓動時創建。在這個應用程序中,啓動時的創建非常有意義。 – Ryan 2010-07-06 10:56:29

1

SubSonic SimpleRepository通常很好地處理這種情況(除了外鍵關係)。

通常我會傾向於不通過代碼創建和維護數據庫和/或表,因爲這很容易在你的臉上炸燬。

1

對於這種類型的上下文,Sqlite具有「create table if not exist」語法。 (檢查http://www.sqlite.org/lang_createtable.html)大多數庫還可以選擇在連接上創建新的sqlite數據庫文件(如果它尚不存在)。

2

通常我會說,表的不存在意味着某個地方存在問題。動態創建的表通常是出錯的標誌,如果它們是標準表(例如tblUsers),那麼它們應始終存在並已設置爲設置過程的一部分。

我能想到的那種檢查存在的時代是有道理的,一旦你在代碼開發中有一定的距離,並且升級數據庫來添加額外的表,但是希望你的代碼使用這個新設計和舊的。在這種情況下,在嘗試使用它們之前檢查表的存在是有道理的。

一般來說,雖然你應該知道你的數據庫裏有哪些表,所以不需要檢查它們的存在。而我完全失去了爲什麼你會試圖訪問不存在的數據庫......你是否想過一種懶惰的設置過程,可以在新的客戶端(或類似的)上快速添加新的客戶端(或類似的)數據庫創建?如果是這樣的話,我會有一個過程來創建和設置這些新的數據庫。

3

不,在代碼中創建表是不正常的。如果您需要關係數據庫,則需要在使用前進行設計。關係數據庫不會被忽略。

如果你從來沒有做過這個已經,這裏是介紹對象...... http://www.databasedev.co.uk/design_basics.html

(很抱歉,如果你知道這一切,我的意思不是光顧。)

+0

使用前設計數據庫是正常的。但對於使用基於文件的數據庫的桌面應用程序,通過代碼創建數據庫可能是適當的。這在許多應用程序共享一個服務器數據庫的企業環境中是不同的。 – MarkJ 2010-07-06 12:59:18

+0

你的意思是安裝它嗎?我認爲Ryan在應用程序運行時意味着;這真的很正常嗎?我的意思是,除了數據庫定義工具。 或者我在這裏得到了棒的錯誤結局? – 2010-07-06 13:15:47

+1

這是不正確的。在某些情況下,商業應用程序創建表甚至整個數據庫。針對各種客戶提供的數據庫服務器運行的應用程序通常創建整個數據庫作爲安裝過程的一部分。在新版本中發佈的應用程序通常會在每個版本中升級其數據庫(包括添加表)。 – 2010-07-06 15:15:03

0

關係數據庫允許輕鬆共享數據。

您可以在不需要共享數據時使用文件。

對於存儲文件信息,DataSet序列化是一個很好的選擇。您維護像關係數據庫一樣結構化的數據。

XML序列化是緩慢的,但你可以使用的BinaryFormatter有:

RemotingFormat = SerializationFormat.Binary 

此選項使快速和緊湊的二進制序列化。

Code-Project包含一個「快速序列化」文章。但這不是標準。

1

在編寫應用程序之前,您應該知道數據的結構。

儘可能將數據和應用程序分開。

使用數據訪問層還意味着如果您已經有Windows應用程序(例如),然後想要創建Web前端,則可以輕鬆地重新使用DAL。

如果數據訪問被嵌入到應用程序中,那麼重用該代碼將變得更加困難。

+0

......此外,如果數據庫模式創建被嵌入到應用程序中......不寒而慄! – onedaywhen 2010-07-07 12:45:58

0

答案取決於項目的性質。

如果這是一個帶有單個實例的內部系統,那麼在您更新軟件時,節省一些開發時間並手動更新數據庫是合理的。在這種情況下,你不用擔心你的軟件會添加表格。

如果您將此軟件提供給客戶或組織內的遠程站點,並且安裝和升級發生在「現場」,那麼每個新版本的軟件都應該自行升級數據庫是合理的。您不一定希望在每個SQL命令之前執行此檢查,而不一定要在每次運行該軟件時進行檢查。您可以在數據庫某處存儲「數據結構版本號」,並在啓動時檢查該數字,如果該數字低於當前版本,則僅應用結構更新。

0

許多RDBMS支持DDL SQL語句。 ADOX可以與一些數據庫一起使用來完成創建新表等操作。我認爲這根本不是特別奇特的,特別是當一個程序使用某種「嵌入式」基於文件的數據庫作爲內部數據存儲或者甚至作爲輸出格式時。

根據需要創建索引,約束,關係等沒有問題。例如:

Private Const WG_CONNSTRING As String = _ 
     "Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Engine Type=5;" _ 
    & "Jet OLEDB:Create System Database=True;" _ 
    & "Data Source='$MDB$.mdw'" 
Private Const DB_CONNSTRING As String = _ 
     "Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Engine Type=5;" _ 
    & "Jet OLEDB:System Database='$MDB$.mdw';" _ 
    & "Data Source='$MDB$.mdb'" 

'Exits with new MDB created, populated from initial data 
'in text files, and cnDB left open. 

Dim catDB As Object 'Don't early-bind ADOX objects. 

Set catDB = CreateObject("ADOX.Catalog") 
catDB.Create Replace$(WG_CONNSTRING, "$MDB$", MDB_NAME) 
catDB.Create Replace$(DB_CONNSTRING, "$MDB$", MDB_NAME) 

Set cnDB = catDB.ActiveConnection 
With cnDB 
    .Execute "CREATE TABLE Fruits (" _ 
      & "FruitID IDENTITY NOT NULL CONSTRAINT PK_FruitID PRIMARY KEY," _ 
      & "Fruit TEXT(50) WITH COMPRESSION NOT NULL UNIQUE" _ 
      & ")", _ 
      , adCmdText 
    .Execute "CREATE TABLE Pies (" _ 
      & "PieID IDENTITY NOT NULL CONSTRAINT PK_PieID PRIMARY KEY," _ 
      & "Pie TEXT(50) WITH COMPRESSION NOT NULL," _ 
      & "FruitID INTEGER NOT NULL CONSTRAINT FK_FruitID " _ 
      & "REFERENCES Fruits (FruitID)" _ 
      & ")", _ 
      , adCmdText 
    .Execute "CREATE VIEW PiesView (ID, Pie, Fruit) AS " _ 
      & "SELECT PieID AS ID, Pie, Fruit " _ 
      & "FROM Pies LEFT OUTER JOIN Fruits " _ 
      & "ON Pies.FruitID = Fruits.FruitID", _ 
      , adCmdText 
    .Execute "CREATE PROC InsertPie(NewPie TEXT(50), FruitName TEXT(50)) AS " _ 
      & "INSERT INTO Pies (Pie, FruitId) " _ 
      & "SELECT NewPie, Fruits.FruitId FROM Fruits " _ 
      & "WHERE Fruit = FruitName", _ 
      , adCmdText 
End With