英文:
Packaging database into application seamlessly for users
问题
我想创建一个桌面应用程序,使用关系型数据库(比如PostgreSQL - 假设在这个应用程序中我最好使用PostgreSQL)。
我希望用户不知道数据库的存在。目前,我不得不在我的本地计算机上安装PostgreSQL,并让我的应用程序与之通信。
我正在使用Go语言。
我该如何避免这种情况?
英文:
I want to create a desktop application that uses a relational database (such as postgres - let's say my best case scenario is to use postgres in this application).
I want users to be unaware of the database. Currently, I had to install postgres into my local computer and have my application communicate with that.
I am using Go.
How can I avoid this?
答案1
得分: 5
您正在寻找一个嵌入式数据库。
对于 PostgreSQL 来说,这不是一个理想的工作方式,但是您可以通过一些小心处理的方式来使用它。
请不要捆绑安装程序并无人值守运行。当用户稍后去安装 PostgreSQL 时,他们会非常困惑,因为他们会看到它已经在他们的计算机上,但他们不知道为什么,谁安装了它,或者密码是什么。
相反,在您的应用程序的 %APPDATA%
目录下(或者对于多用户共享的情况下,在 %PROGRAMDATA%
目录下)使用 initdb
创建一个新的数据目录。设置一个自定义端口(不要使用默认的 5432)。使用 pg_ctl register
创建一个新的服务,以 NETWORKSERVICE
身份运行,或者只需使用 pg_ctl
按需启动/停止。这样,您就不会干扰任何现有的 PostgreSQL 安装或新安装,并且拥有一个专门为您的应用程序而设的私有 PostgreSQL。
请为用户提供另外一种选择,即提供现有 PostgreSQL 的连接字符串。如果应用程序坚持使用它们自己的嵌入式副本,而您不希望这样,那将会很麻烦。
通常最好考虑使用 SQLite、H2、Derby、Firebird 或其他嵌入式数据库。
英文:
You're looking for an embedded database.
This isn't an ideal job for PostgreSQL, but you can use it that way with a bit of care.
Please don't bundle the installer and run it unattended. Users who later go to install PostgreSQL will be very confused when they see it's already on their computer but they don't know why, who installed it, or what the password is.
Instead initdb
a new datadir inside your app's %APPDATA%
or (for multiuser shared) in %PROGRAMDATA%
. Set a custom port (don't use the default 5432). Create a new service with pg_ctl register
, running as NETWORKSERVICE
, or just start/stop on demand with pg_ctl
. That way you won't get in the way of any existing PostgreSQL installs or new ones and have a private PostgreSQL just for your app.
Please offer users the option of instead supplying a connection string for an existing PostgreSQL though. It's a pain if apps insist on using their own embedded copy when you don't want them to.
Often it's better to look at using SQLite, H2, Derby, Firebird, or one of the other embedded DBs, though.
答案2
得分: 2
简短版本,你真的不能这样做,最好的方法是使用SQLite或类似的数据库。
详细版本,如果你真的非常想要这样做,你可以为每个目标平台创建多个无人值守安装程序,将其嵌入到你的应用程序中,并在第一次运行时进行安装。
但这样做实在是太丑陋了,大多数用户(包括我自己)都不会使用它。
你可以提到你的软件依赖于X和Y,并提供有关如何手动安装依赖项的信息。
英文:
Short version, you really can't, your best bet is to use SQLite or similar.
Long version, well, if you really really want to, you can create multiple unattended installers for your database that targets each platform you want, embed it into your application and install it on the first run.
Now that is just ugly and most users (myself included) would outright never use it.
You can always mention that your software depends on X and Y and provide information about how to manually install the dependencies.
答案3
得分: -1
这个电子邮件线程揭示了在古老的Windows系统中正确的操作方法。很可能有类似的帖子,其中更详细地介绍了这个问题。
链接:https://www.postgresql.org/message-id/4D2FFF07.6060409@aimproductions.be
嗨,
在2011年1月14日,Craig Ringer写道:
> 在2011年1月14日06:26 AM,Jensen Somers写道:
>
>> 我知道一些应用程序(Poker Tracker 3是我首先想到的)
>
> 这不是一个好的例子,正如在这个列表上出现的关于它的问题数量所示,以及它们捆绑的非常古老的Pg版本。
>> 安装PostgreSQL在他们的安装过程中
>> 并设置初始数据库。我有点弄明白了如何做到这一点,但我不知道如何在设置过程中处理已经存在的安装。
> 我猜你是指在你自己的应用程序安装程序中调用postgresql exe安装程序进行静默安装?
> 就个人而言,如果我在我的(Windows)应用程序中捆绑Pg,我不会这样做,因为正如你提到的,它可能会干扰用户想要手动进行的任何现有或将来的Pg安装。它还将单独显示在添加/删除程序中,我认为这是不希望的,因为它只是作为您的应用程序的一个组件进行安装。
> 如果我的应用程序需要Pg,我可能会在我的安装程序中捆绑Pg安装目录,并将其复制到我的程序的安装目录中。然后,我会创建一个以我的应用程序命名的非登录用户帐户(而不是“postgres”),设置服务(同样以我的应用程序命名),并调用initdb在该服务帐户下创建数据库。我会生成一个postgresql.conf文件,其中包含一个半随机的相当高的端口号,在目标机器上尚未使用,以避免与常用的postgresql端口冲突。所有这些都可以使用大多数安装程序提供的脚本语言或简单的Windows命令行工具(如“net.exe”和相关工具)来完成。如果您的安装程序特别有限,您可以编写并捆绑一个简单的辅助程序,供其调用以执行工作。我的卸载程序将提示用户询问是否要删除数据以及程序;如果他们说是,我将删除数据目录和安装期间创建的用户帐户。
> 这样,您的PostgreSQL实例是私有的,不会与用户可能想要执行的任何操作冲突。您可以在升级应用程序时升级它,在应用程序中为其提供备份功能等等,而用户不必关心幕后发生了什么。
> 如果这不可行,我唯一考虑的其他选择是提供一个postgresql安装程序,并要求用户在尚未安装它的情况下安装它。然后,我会提示输入数据库主机、端口、用户名、密码和数据库名称,然后使用提供给我的信息。这几乎肯定是在UNIX/Linux平台上应该采取的方法。
> - Craig Ringer
将其作为我的应用程序的一部分捆绑更好。我不知道是否可能,但这将解决一些问题。主要是数据保护。需要存储的数据不应该被用户更改。如果他们通过root密码访问数据库,这将是使用安装程序或现有服务器的情况,他们可以操纵数据。实施您建议的解决方案将防止所有这些问题,这是一个完美的解决方案。
谢谢,我知道我今天要做什么了!
- Jensen
英文:
This email thread shine some light into proper ways to do it in ancient windows. Most likely there are similar posts in which they go more into detail.
https://www.postgresql.org/message-id/4D2FFF07.6060409@aimproductions.be
Hi,
On 14/01/2011 7:35, Craig Ringer wrote:
> On 01/14/2011 06:26 AM, Jensen Somers wrote:
>
>> I know that some applications (Poker Tracker 3 is the first one that
>> comes to my mind)
>
> It's not a good example, either, as demonstrated by the number of
> questions that pop up about it on this list, and the incredibly
> ancient versions of Pg that they bundle.
>
>> install PostgreSQL during their installation process
>> too and setup the initial database. I sort of figured out how to do
>> this, but I don't know how to deal with an already existing installation
>> during setup.
>
> I take it you're talking about doing a silent install using the
> postgresql exe installer, by invoking it as part of your own app's
> installer?
>
> Personally, that's not how I'd do it if I were bundling Pg in my
> (Windows) app, because as you mentioned it may interfere with any
> existing or future Pg install the user wants to do manually. It'll
> also show up separately in add/remove programs, which I think is
> undesirable when it's just being installed as a component of your app.
>
> If my app required Pg, I'd probably bundle the Pg installation tree in
> my installer and copy it into my program's install directory. I'd then
> create a non-login user account named after my application (NOT
> "postgres"), set up the service (again named for my application), and
> invoke initdb to create the database under that service account. I'd
> generate a postgresql.conf with a semi-random fairly high port number
> that wasn't already in use on the target machine, to avoid conflicting
> with the commonly used postgresql port. All this can be done using the
> scripting languages provided by most installers, or via simple Windows
> command line tools like "net.exe" and friends. If your installer is
> particularly limited, you can always write and bundle a simple helper
> program for it to invoke to do the work. My uninstaller would prompt
> the user to ask if they wanted to remove data as well as the program;
> if they said yes I'd remove the datadir and the user account I'd
> created during installation.
>
> This way, your instance of PostgreSQL is private to your app and
> doesn't conflict with anything the user might want to do. You can
> upgrade it when you upgrade your app, provide backup facilities for it
> in your app, etc etc without the user having to care what's behind the
> scenes.
>
>
> If that wasn't viable, the only other option I'd consider would be
> providing a postgresql installer and asking the user to install it if
> they didn't already have it installed. I'd then prompt for the
> database host, port, username, password and database name to connect
> to, and would just use what was provided to me. This is almost
> certainly how it should be done on UNIX/Linux platforms.
>
> --
> Craig Ringer
Bundling it as part of my application is even better. I didn't knew if
that would be possible, but it would solve some of the issues. Mainly
data protection. The data that needs to be stored should not be altered
by users. If they have access to the database via a root password, which
would be the case when using the installer or an existing server they
can manipulate the data. Implementing your suggested solution would
prevent all that, which makes it a perfect solution.
Thanks, I know what I'll be doing today!
- Jensen
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论