问题
I am new to database design and I'm trying to get into the best practices early. So far everywhere I look their seems to be an agreement that you "Create the table names at the start of development, and insert your data, do not use variables for table names. Well I was looking to make an asset management system and I can't get past what seems like a design flaw. This software would be very similar to "quickbase" if you're familiar.
Here is the scenario.
- User can create accounts, each account is in a table of accounts that has data inside that links back to the other related tables.
- Inside each account there is as many catagories as they need to track info such as:
- Financials
- Trips
- Tasks
- etc
Now each one of these categories would hold a significant amount of information and would require it's own table. Obviously I could use relationships to connect these tables back to the account but their is a problem (I think). The user can create as many accounts as they need and every time they do their will need to be a number of other tables created along with it. Such as "account_name_financials_table" etc.
So my question is: Can this be possible to do without using variables for table names when dynamically creating them. OR is this a scenario where it would be considered acceptable to use variables for table names when creating them.
If this is too localized or vague please let me know and I will provide any further details needed.
Thank you for your time
EDIT
In response to Davids awesome answer.
I fully understand now that each account is actually just an entry, or a row into one table that would hold the information for each account. The column names would then describe the data that describes my account and subsequently relates to the other tables.
Now the core of this problem is that when I create the account there are other tables that need to be created, or at least I think they do. This would be a financials table for instance that holds specific information about that accounts financials. There is a one to one relationship on these tables. Meaning Account A can only have 1 set of financials for the specific account. So when I create Account B the financials table I currently have would no longer have relevant column names, rows, or data for Account B. So when I create these new tables for Account B, they would more then likely need to be done dynamically. With this being said, how would I create them without variable names?
Or perhaps I'm still missing the point. A thought occurs to me that perhaps I could have one large financial table that holds information for all accounts and that information is defined/related back to the specific account by 'id' or some other unique fk pk identifier?
回答1:
Don't think of a table as an entity in your domain, think of it as a definition of the what describes an entity and each record in that table is an instance of that entity.
Given that, this statement becomes incorrect:
User can create accounts, each account is its own table.
The Account
(or Accounts
, depending on your naming conventions) table is the schematic definition of what describes an Account entity. It might have columns like the Account's name, the date it registered, things like that. Each record in the Account
table is an Account. So there would be one Account
table which holds all of the Accounts in the domain.
Inside each account there is 4 - 8 catagories they can track
That statement seems a little counterintuitive to describe relational data. How about:
Each Account can also have additional data related to it, such as...
And now the next lines aren't describing something that's "inside" an Account, but rather another entity in the domain which happens to relate to an Account:
- Financials
- Trips
- Tasks
- etc.
Each of these is an entity in its own right (or can be anyway, the terms currently are a little vague) which don't necessarily describe an Account, but themselves are described by an Account. That is, an Account doesn't point to a Task. A Task points to an Account. The Account itself is a data point which describes the Task.
Thus, each of these becomes tables in their own right, in which the records have foreign keys back to the Account
table. Something as simple as this:
Task
----------------------
ID | int
AccountID | int
Description | nvarchar
ScheduledOn | datetime
And so on. Each record in that table (each record represents one Task in the domain) would include an AccountID
value which indicates which Account owns that Task.
The tables should be specific to any particular subset of entities, but should be general to all instances of that particular entity.
You can further customize entities into different types by sub-typing tables. For example, maybe you have different kinds of Accounts and there are different fields which describe them. You might have a single Account
table as above, but would have additional tables where the primary key is also the foreign key to the Account
table. These tables would represent one-to-one relationships to the Account
table and could add more values to a "subset" of Accounts. A table like this, for example:
PreferredAccount
---------------------
AccountID | int (PK, also FK to Account.ID)
PreferredStatus
BecamePreferredOn
And so on. That way you can logically separate your Accounts by type without having to create multiple tables to represent an Account itself.
To get back to the question... Ultimately, when a user creates an Account, they're not changing the schema of the database. They're simply adding a record to the Account
table.
来源:https://stackoverflow.com/questions/17870877/avoid-using-dynamic-table-names-but-how