到目前为止,我的公司一直厌恶数据库,并坚持将所有数据存储在以逗号分隔的文件中。我遇到了一个独特的客户应用程序 - 我相信 - 会受益于关系数据库的使用。该应用程序要求存储有关制造过程的“摘要”数据和多个子过程的“详细”数据。子流程需要链接到流程摘要。
我的问题:在写入此表之前检查表是否存在是正常/适当的,如果表不存在则创建表是否正常?这可能会导致一个更大的问题,因为我正在打字;如果数据库不存在,我应该创建数据库和它需要的任何表吗?
答案 0 :(得分:3)
不,在代码中创建表是不正常的。如果需要关系数据库,则需要在使用前进行设计。关系数据库不容小觑。
如果你以前从未这样做过,那么这里是对这个主题的介绍...... http://www.databasedev.co.uk/design_basics.html
(对不起,如果你知道这一切;我不是故意光顾。)
答案 1 :(得分:3)
使用SQLite,自己创建表是一种很好的方法。您不需要为客户制作比现有更复杂的安装说明,如果数据库完全在您的应用程序内部,他们可能甚至不关心它的格式,只要您的软件可靠而快速。
例如,Firefox目前使用SQLite作为其内部存储,他们从不打扰用户创建数据库。用户也喜欢这样。 :)但是我不会过分担心在引用表之前立即创建数据库:相反,我会将创建逻辑放在应用程序启动或安装时,以较合适的为准。现在在您的应用程序中创建的CSV文件在哪里?是否每次引用它们时都会重新创建它们?或者它们是在初始化或安装例程中创建的吗?
答案 2 :(得分:2)
通常情况下,我会说不存在表格意味着某个地方存在问题。动态创建的表通常是出错的标志,如果它们是标准表(例如tblUsers),那么它们应该始终存在,并且已经设置为设置过程的一部分。
我能想到检查存在的时间是有意义的,一旦你在代码开发中有一定的距离,你升级数据库以添加额外的表,但希望你的代码能够使用这个新设计和旧设计。在这种情况下,在尝试使用表之前检查表的存在是有意义的。
一般情况下,您应该知道数据库中有哪些表,因此不需要检查它们是否存在。我完全迷失了为什么你要尝试访问不存在的数据库...你是否正在考虑某种懒惰的设置过程,其中新的客户端(或类似的)可以快速添加jsut和他们的数据库创建?如果是这样,我将有一个过程来创建和设置这些新数据库。
答案 3 :(得分:1)
SubSonic SimpleRepository通常很好地处理这种情况(外键关系除外)。
一般来说,我倾向于不通过代码创建和维护数据库和/或表格,因为这很容易在你的脸上爆炸。
答案 4 :(得分:1)
对于这种类型的上下文,Sqlite有一个“create table if not exists”语法。 (检查http://www.sqlite.org/lang_createtable.html)大多数库也可以选择在连接上创建新的sqlite数据库文件(如果它尚不存在)。
答案 5 :(得分:1)
在编写应用程序之前,您应该知道数据的结构。
尽可能将数据和应用程序分开。
使用数据访问层还意味着,如果您已经拥有Windows应用程序(例如),然后想要创建Web前端,则可以轻松地重新使用DAL。
如果数据访问嵌入在应用程序中,则重用该代码要困难得多。
答案 6 :(得分:0)
关系数据库可以轻松共享数据。
您可以在不需要共享数据时使用文件。
DataSet序列化是存储文件信息的好选择。您维护的数据结构类似于关系数据库。
Xml序列化很慢,但你可以使用BinaryFormatter:
RemotingFormat = SerializationFormat.Binary
此选项可实现快速紧凑的二进制序列化。
Code-Project包含一篇“快速序列化”文章。但这不是标准的。
答案 7 :(得分:0)
答案取决于项目的性质。
如果这是一个具有单个实例的内部系统,那么在更新软件时节省一些开发时间并使用新表手动更新数据库是合理的。在这种情况下,您不必担心软件会添加表格。
如果您将此软件提供给组织内的客户甚至远程站点,并且“在现场”进行安装和升级,那么每个新版本的软件都应该自行升级数据库是合理的。您不一定要在每个SQL命令之前执行此检查,而不一定要在每次运行软件时执行此检查。您可以在数据库中的某处存储“数据结构版本号”,并在启动时检查该数字,仅在数字低于当前版本时才应用结构更新。
答案 8 :(得分: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