In my Solution I have the following projects
MySystem.Core
MySystem.Core.Data
MySystem.MyAudit1.Core
MySystem.MyAudit1.Core.Data
MySystem.MyAudit2.Core
MySystem.MyAudit2.Core.Data
The number of audit projects could potentially grow to around 20.
The Audit projects all require an "Organisation" reference data table. Rather than duplicate the same reference data table across all audit projects 20 times and try to keep them in sync, my plan is to have a "master" organisation table in the Core project.
This will contain Code and Description for all organisations. Then, in each particular audit project have an OrganisationCode table that contains only the Org Codes relevant to that audit but not the description, and have a view in the audit database that looks up the description from the core Org table as follows:
CREATE VIEW Organisation AS
SELECT d.OrganisationCodeId as 'OrganisationId', d.Code, a.[Description]
FROM MyAudit1.dbo.OrganisationCode d
INNER JOIN [Core].dbo.OrganisationCode a ON d.Code = a.Code
This will mean that if Org descriptions change they can be updated in one place and reflected across all the audits.
However, as you cannot have foreign keys on Views within SQL I had created a foreign key between the OrganisationCode table and whichever other tables in the audit database needs them.
As I have discovered, this of course causes NHibernate to try and return OrganisationCode table rather than the Organisation view and causes my SessionFactory creation to fall over as Nhibernate is looking for OrganisationId in the OrganisationCode table.
Is there an easy way round this which will allow me to have a single description lookup in the core project for reference data that can be used across child projects
Yes the audit tables are spread over separate dbs, but I have got to the route of my problem.
The reason that my SessionFactory creation was falling over is that the Configuration was being passed the audit data assembly for mapping, and my organisation mapping file was in the core data assembly.
Now that I have solved that by adding an organisation mapping file in my audit data assembly, my trust object is returning the description values from the organisation view.
Thanks for looking.
Related
Let us say I need to design a database which will host data for multiple companies. Now for security and admin purposes I need to make sure that the data for different companies is properly isolated but I also do not want to start 10 mysql processes for hosting the data for 10 companies on 10 different servers. What are the best ways to do this with the mysql database.
There are several approaches to multi-tenant databases. For discussion, they're usually broken into three categories.
One database per tenant.
Shared database, one schema per
tenant.
Shared database, shared schema. A tenant identifier (tenant key) associates every row with the right tenant.
MSDN has a good article on the pros and cons of each design, and examples of implementations.
Microsoft has apparently taken down the pages I referred to, but they are on on archive.org. Links have been changed to point there.
For reference, this is the original link for the second article
In MySQL I prefer to use a single database for all tenants. I restrict access to the data by using a separate database user for each tenant that only has access to views that only show rows that belong to that tenant.
This can be done by:
Add a tenant_id column to every table
Use a trigger to populate the tenant_id with the current database username on insert
Create a view for each table where tenant_id = current_database_username
Only use the views in your application
Connect to the database using the tenant specific username
I've fully documented this in a blog post:
https://opensource.io/it/mysql-multi-tenant/
The simple way is: for each shared table, add a column says SEGMENT_ID. Assigned proper SEGMENT_ID to each customer. Then create views for each customer base on the SEGMENT_ID, These views will keep data separated from each customers. With this method, information can be shared, make it simple for both operation & development (stored procedure can also be shared) simple.
Assuming you'd run one MySQL database on a single MySQL instance - there are several ways how to distinguish between what's belonging to whom.
Most obvious choice (for me at least) would be creating a composite primary key such as:
CREATE TABLE some_table (
id int unsigned not null auto_increment,
companyId int unsigned not null,
..
..
..,
primary key(id, company_id)
) engine = innodb;
and then distinguishing between companies by changing the companyId part of the primary key.
That way you can have all the data of all the companies in the same table / database and at application level you can control what company is tied to which companyId and determine which data to display for certain company.
If this wasn't what you were looking for - my apologies for misunderstanding your question.
Have you considered creating a different schema for each company?
You should try to define more precisely what you want to achieve, though.
If you want to make sure that an HW failure doesn't compromise data for more than one company, for example, you have to create different instances and run them on different nodes.
If you want to make sure that someone from company A cannot see data that belong to company B you can do that at the application level as per Matthew PK answer, for example
If you want to be sure that someone who manages to compromise the security and run arbitrary SQL against the DB you need something more robust than that, though.
If you want to be able to backup data independently so that you can safely backup Company C on mondays and Company A on sundays and be able to restore just company C then, again, a purely application-based solution won't help.
Given a specific DB User, you could give a user membership to group(s) indicating the companies whose data they are permitted to access.
I presume you're going to have a Companies table, so just create a one-to-many relationship between Companies and MySQLUsers or something similar.
Then, as a condition of all your queries, just match the CompanyID based on the UserID
in my file Generate_multiTanentMysql.php i do all steps with PHP script
https://github.com/ziedtuihri/SaaS_Application
A Solution Design Pattern :
Creating a database user for each tenant
Renaming every table to a different and unique name (e.g. using a prefix ‘someprefix_’)
Adding a text column called ‘id_tenant’ to every table to store the name of the tenant the row belongs to
Creating a trigger for each table to automatically store the current database username to the id_tenant column before inserting a new row
Creating a view for each table with the original table name with all the columns except id_tenant. The view will only return rows where (id_tenant = current_database_username)
Only grant permission to the views (not tables) to each tenant’s database user
Then, the only part of the application that needs to change is the database connection logic. When someone connects to the SaaS, the application would need to:
Connect to the database as that tenant-specific username
I'm pretty sure this is a basic question, but I'll be darned if I can find an example that helps me understand the proper way to do what I need to do.
In MS Access 365 I am creating a maintenance tracking database. I have a table with basic employee information. Employees can both perform maintenance tasks and verify maintenance tasks. I can set up a one to many reference using the Employee ID PK as a FK in my task log table for who performed the task. Obviously, I can't set up another one to many relationship to a field of who verified the task.
I already have the task details in a separate table which is referenced by the task log table. Am I just being stubborn in not splitting my task log table into task performed and task verified? Is there another way to normalize this data?
Obviously, I can't set up another one to many relationship to a field of who verified the task.
Yes, you totally can.
When you drag&drop the 2nd relation, Access will ask if you want to edit the existing relation or create a new one.
It will display like this, but it is actually 2 one-to-many relations from User to Log.
My organization works on Spring MVC with Hibernate. We always specify foreign key constraints in mapping file, like for person and contactList in Person.hbm.xml
<set name="ContactList">
<key column="PersonId" foreign-key="Fk_Peson_Contact"/>
<one-to-many class="Sample.Model.Contact"/>
</set>
This mapping will create one-to-many relationship between Person and Contact, and keep PersonID as foreign key column in the Contact table.
But, now organization has decided not to mention any kind of relationship in mapping file, means in above case Person mapping will not have any kind of one-to-many mapping instead of this Contact mapping will have property <property name="FK_PersonID"/> which will create column to hold personID. In this scenario table Person and Contact will look same but the difference is their is no relationship between Person and Contact coz no mapping is specified.
In such case if we want to fetch person's contactList then we have to fire two queries one to fetch person another for its contactList. let suppose we want to fetch personList with its contactList then we have to For loop on PersonList and fetch its ContactList which will fire number of queries.
When i ask why not specify relationship then senior said ,
If foreign key is in DB then we can't do slicing and partitioning.
When we fire join query DB takes more time to execute it.Which may slow down DB server.
But,my question is -
if i do For looping on personList then it will fire number of queries to fetch contacts is it feasible?
can such looping slow down application or application server?
what if i want to fetch personList with its conatctList,AddressList,QualificationList, Does this cause n+1 issue?
Which Scenario is more beneficial whether to specify mapping or not.
Well, I one of the early demos of partitioning in (MS) SQL by microsoft they showed a query which selected from a partioned table with data populated across several partions, and it used its indexes and stats to not even bother accessing partitions that had no (relevant) data. Of course if you dont have a fk constaint then it cant use the index and stats to know the fk conforms. I'd be fairly sure it would be covered by Kalen Delaney in her book (for the relevant version of MSSQL). The key is that the stats will contain the necessary information to prevent unnecessary seeks. The demo actually used a union to easily demo the effect.
I have an application that ships to the customer with a JET database including a relationship diagram which more savvy users are invited to view to gain insight into the construction of the database.
I also have code in my application to update the database structure when new versions require new tables, new columns, or modified queries. I do this by pushing SQL through the ADO connection it works fine.
The problem is that if I add a new table with a constraint that relates it to an existing table (for instance, I add EmployeeHobbies with an FK relationship to an existing PK in Employees), while the table is constructed correctly the new relationship does not appear in the relationship diagram. Over time the diagram becomes progressively less complete.
Is there a programmatic method to force Access to update its relationship diagram from constraint information in the database or, failing that, is the relationship diagram stored in some hidden system object that I can update directly to reflect my changes?
Edit: I failed to make clear that my application is written in Delphi, not MS Access. Users who have a copy of MS Access can see the relationship diagram, others cannot.
I do not know if RunCommand will suit, but for what it's worth:
DoCmd.RunCommand acCmdRelationships
DoCmd.RunCommand acCmdShowAllRelationships
You may be able to leverage Stephen Lebans' SaveRelationshipView for this. His code saves properties for each item from the Relationships view to a table. Later the same layout view can be recreated from the table.
You could adjust your copy of the Relationships view to determine the values to include for a new row in the tblRelationshipViews table. Then let the users recreate their Relationships view based on the updated table information. Perhaps you could even automate to do it for them automatically.
I am using ASP.NET MVC2 on top of a MySQL database in VS2008. I am using the MySQL ADO.NET connector 6.2.3 to provide the connection for the ADO.NET Entity Data Model.
This is mostly working ok, however navigating via foreign keys is causing me a real headache!
Here is a simplified example..
Car (Table)
CarID PK
Colour
Doors
ManufacturerID FK
Manufacturer (Table)
ManufacturerID PK
Name
In the edmx file I can see the 1-many relationship shown as a navigation property in the both the Car and Manufacturer tables. I create a Models.CarRepository that allows me to returns a IQueryable.
At the View I want to be able to display the Manufacturer.Name for each car. This is not accessible via the object I get returned.
What is best way to implement this? Have I encountered a limitation of the Entity Framework/MySQL combination?
Eager loading of the related records needs to be enabled in the Model Repository. Something like:
var allCars = from c in automobileEntites.Car.Include("Manufacturer")
select c;
This then makes the related records available for subsequent query/display.