I am designing an intranet application. This intranet is for a parent company which will have multiple sub companies under it. Each employee will belong to a company. I need to store only the name of the company as of now.
Now to maintain external relations to partners and clients we need to store their company. Here also, I need to store only the name.
My questions is - Is it better to keep these in two separate tables one company table for internal and the other for external? Or is it better to have one table and identify internal and external companies with a FLAG.
The generic question being if two tables have the same structure but belong to differ
Please suggest.
Thanks!
Better, in a sense of normalized database design, would be to have one company table and second table of company types instead of a flag column. You'll be able to distinguish external partners later without having to add another flag.
Related
I am getting started in microservices architectures and I have a couple of questions about the data persistence and databases.
So my understanding is each microservice has it's own database (not necessarily, but usually). But given that case, consider a usual social media platform with users, posts and comments. There will be two microservices, a user's microservice and a posts' microservice. The user's database have a users table and the posts' database has posts and comments tables.
My question is on the posts microservice, because each post and comment has an author, so usually we would create the foreign key pointing to the user's table, however this is in a different database. What to do then? From my perspective there are 2 options:
Add the authorId entry to the table but not the foreign key constrain. If so, what would happen in the application whenever we retrieve that user's data from the user's microservice using the authorId and the user's data is gone?
Create an author's table in the posts' database. If so, what data should that table contain other than the user's id?
It just doesn't feel right to duplicate the data that is already in the user's database but it also doesn't feel right to use the user's id without the FK constraint.
One thing to note, data growth is quite different
Users -> relatively static data.
Posts & Comments -> Dynamic and could be exponentially high compared to users data.
Two microservices design looks good. I would prefer option-1 from your design.
Duplication is not bad, In normal database design this is normal to have "Denormalization" for better read performance. This is also helping in decoupling from users table , may help you to choose different database if require. some of your question what if users data is missing and posts is available, this can be handle with business logic and API design.
I am designing data base for inventory management system which is used by nearly 10 to 15 companies. This database contains nearly 25 tables.For designing database i'm planning to use shared schema architecture(ie each schema corresponding to a company and these all schemas are to be placed in a single database).
i want to know whether it is reliable to use shared schema architecture.
can any one please tell me is it correct decision to use above mentioned architecture.
Thanks in advance..
If I read your question, you are suggesting that each company has its own schema. This means two things:
If you decide to implement a basic change in the schema (ie not a change that one company requests), then you will have to implement this change in all the schemae.
You will probably have to implement different logic in your front
end program for each company.
Better you should develop one schema for the entire database; each table would have a field called 'CompanyID' which naturally would define to which company each row belongs. This field would be a foreign key to the Companies table.
I'm certainly no DBA and only a beginner when it comes to software development, so any help is appreciated. What is the most secure structure for storing the data from multiple parties in one database? For instance if three people have access to the same tables, I want to make sure that each person can only see their data. Is it best to create a unique ID for each person and store that along with the data then query based on that ID? Are there other considerations I should take into account as well?
You are on the right track, but mapping the USER ID into the table is probably not what you want, because in practice many users have access to the corporations data. In those cases you would store "CorpID" as a column, or more generically "ContextID". But yes, to limit access to data, each row should be able to convey who the data is for, either directly (the row actually contains a reference to CorpID, UserID, ContextID or the like) or it can be inferred by joining to other tables that reference the qualifier.
In practice, these rules are enforced by a middle tier that queries the database, providing the user context in some way so that only the correct records are selected out of the database and ultimately presented to the user.
...three people have access to the same tables...
If these persons can query the tables directly through some query tool like toad then we have a serious problem. if not, that is like they access through some middle tier/service layer or so then #wagregg's solution above holds.
coming to the case when they have direct access rights then one approach is:
create database level user accounts for each of the users.
have another table with row level grant information. say your_table has a primary key column MY_PK_COL then the structure of the GRANTS_TABLE table would be like {USER_ID; MY_PK_COL} with MY_PK_COL a foreign key to your_table.
Remove all privileges of concerned users from your_table
Create a view. SELECT * FROM your_table WHERE user_id=getCurrentUserID();
give your users SELECT/INSERT/UPDATE rights on this view.
Most of the database systems (MySQL, Oracle, SQLServer) provide way to get current logged user. (the one used in the connection string). They also provide ways to restrict access to certain tables. now for your users the view will behave as a normal table. they will never know the difference.
a problem happens when there are too many users. provisioning a database level uer account to every one of them may turn difficult. but then DBMS like MsSQLServer can use windows authentication, there by reducing the user/creation problem.
In most of the scenarios the filter at middle tier approach is the best way. but there are times when security is paramount. Also a bug in the middle tier may allow malicious users to bypass the security. SQL injection is one thing to name. then you have to do what you have to do.
It sounds like you're talking about a multi-tenant architecture, but I can't tell for sure.
This SO answer has a summary of the issues, and links to an online article containing details about the trade-offs.
Almost every web application now allows you to setup a basic profile (Even Stack Exchange does). The question is how should you be storing the data in your database?
Should you just add more columns to your users database table, or should you setup another table called user_profiles that has a foreign key of user_id?
This is quite subjective:
Separate table
easier to fetch user without profile
when some user doesn't have a profile (one-to-one optional relationship), you don't pay anything in terms of storage
sharing profile (?!?) - can't imagine such a scenario, but...
Single table
no JOINs required when loading
related information in one place
strong one-to-one (typically every user will have a profile, maybe created implicitly) relationships tend to be merged to single table
I have a full multi-tenant database with TenantID's on all the tenanted databases. This all works well, except now we have a requirement to allow the tenanted databases to "link to" shared data. So, for example, the users can create their own "Bank" records and link accounts to them, but they could ALSO link accounts to "global" Bank records that are shared across all tenants.
I need an elegant solution which keeps referential integrity
The ways I have come up with so far:
Copy: all shared data is copied to each tenant, perhaps with a "System" flag. Changes to shared data involve huge updates across all tenants. Probably the simplest solution, but I don't like the data duplication
Special ID's: all links to shared data use special ID's (e.g. negative ID numbers). These indicate that the TenantID is not to be used in the relation. You can't use an FK to enforce this properly, and certainly cannot reuse ID's within tenants if you have ANY FK. Only triggers could be used for integrity.
Separate ID's: all tables which can link to shared data have TWO FK's; one uses the TenantID and links to local data, the other does not use TenantID and links to shared data. A constraint indicates that one or the other is to be used, not both. This is probably the most "pure" approach, but it just seems...ugly, but maybe not as ugly as the others.
So, my question is in two parts:
Are there any options I haven't considered?
Has anyone had experience with these options and has any feedback on advantages/disadvantages?
A colleague gave me an insight that worked well. Instead of thinking about the tenant access as per-tenant think about it as group access. A tenant can belong to multiple groups, including it's own specified group. Data then belongs to a group, possibly the Tenant's specific group, or maybe a more general one.
So, "My Bank" would belong to the Tenant's group, "Local Bank" would belong to a regional grouping which the tenant has access to, and "Global Bank" would belong to the "Everyone" group.
This keeps integrity, FK's and also adds in the possibility of having hierarchies of tenants, not something I need at all in my scenario, but a nice little possibility.
At Citus, we're building a multi-tenant database using PostgreSQL. For shared information, we keep it in what we call "reference" tables, which are indeed copied across all the nodes. However, we keep this in-sync and consistent using 2PC, and can also create FK relationships between reference and non-reference data.
You can find more information here.