I am trying to make a form which require 4 fields to be filled.
Date
Material(drop down will give options to select from e.g Cement, Bricks etc)
Quantity
Price.
I want to push this data into different tables depending on the selected Material e.g
The data will be pushed into the brick's table if the user selects 'Brick' from the material's drop down.
The data will be pushed into the cement's table if the user selects 'Cement' from the material's drop down.
Simultaneously I want to push data into a table named 'All_Transactions" regardless of the materials selected just like in a ledger.
Summary:
The data will be pushed into 2 tables simultaneously
All_transactions table
{Material}_table
Kindly help me out.
You should rethink your schema. It will require you to introduce a new table each time you introduce a new kind of material. Better create these tables
TABLE Material:
MaterialID (Autonumber, Long Integer, Primary Key)
Name (Text)
TABLE Order:
OrderID (Autonumber, Long Integer, Primary Key)
Date (DateTime)
TABLE OrderItem:
OrderItemID (Autonumber, Long Integer, Primary Key)
OrderID (Long Integer, Foreign Key)
MaterialID (Long Integer, Foreign Key)
Quantity (Double)
Unit (Text)
Order Material
┌─────────────┐ ┌───────────────┐
│ OrderID PK │ │ MaterialID PK │
│ Date │ OrderItem │ Name │
└─────────────┘ ┌────────────────┐ └───────────────┘
▲ │ OrderItemID PK │ ▲
└───────────┤ OrderID FK │ │
│ MaterialID FK ├───────────────┘
│ Quantity │
│ Unit │
└────────────────┘
Like this, introducing a new material only consists of adding a new record to the Material table. This not only reduces the number of tables, but also the amount of programming, queries, forms, reports etc.
You will probably need some more tables for customers etc.
The database schema is the fundament of your application. With a good schema you can succeed in making a good application. If the schema is bad, the game is lost in advance.
Related
Im pretty new to BI modelling and have been assigned a project to create a BI solution for a Patient Administration System (millions of rows). There are no sales or additive information in the system. Basically all of the Measures will be Counts. Im finding it difficult to locate good examples/tutorials of the model I require as most BI implementations seem to be based around Sales.
If anyone could help with my modelling problem I would be very grateful.
Tables (columns excluded for brevity) within the implementation are
Patient (
Key -> Surrogate Key
PatientId -> Source System Id
Name -> Text
AgeKey -> FK to Age Dimension Table
NationalityKey -> FK to Nationality Dimension Table
DateOfBirthKey -> FK to Date Dimension Table
GenderKey -> FK to Gender Dimension Table
etc.
)
Referral (
Key -> Surrogate Key
ReferralId -> Source System Id
PatientKey -> FK to PatientTable
ReferredAtDateKey -> FK to Date Dimension Table
PriorityKey -> FK to Priority Dimension Table
SpecialtyKey -> FK to Specialty Dimension Table
etc
)
WaitingList(
Key -> Surrogate Key
WaitingListId -> Source System Id
ReferralKey -> FK to ReferralTable
AddedToListDateKey -> FK to Date Dimension Table
RemovedFromListDateKey -> FK to Date Dimension Table
StatusKey -> FK to Waiting List Status Table
Position -> int
etc
)
I need to be able to build reports/charts around Patients, Referrals and Waiting Lists so I am using Views to create my Fact tables in SSAS. Examples are:
FactPatient (
Key -> Surrogate Key
PatientId -> Source System Id
Name -> Text
AgeKey -> FK to Age Dimension Table
NationalityKey -> FK to Nationality Dimension Table
DateOfBirthKey -> FK to Date Dimension Table
GenderKey -> FK to Gender Dimension Table
etc.
)
FactReferral (
Key -> Surrogate Key
ReferralId -> Source System Id
-- Patient
Name -> Text
AgeKey -> FK to Age Dimension Table
NationalityKey -> FK to Nationality Dimension Table
DateOfBirthKey -> FK to Date Dimension Table
GenderKey -> FK to Gender Dimension Table
etc.
-- Referral
ReferredAtDateKey -> FK to Date Dimension Table
PriorityKey -> FK to Priority Dimension Table
SpecialtyKey -> FK to Specialty Dimension Table
etc
)
FactWaitingList(
Key -> Surrogate Key
WaitingListId -> Source System Id
-- Patient
Name -> Text
AgeKey -> FK to Age Dimension Table
NationalityKey -> FK to Nationality Dimension Table
DateOfBirthKey -> FK to Date Dimension Table
GenderKey -> FK to Gender Dimension Table
etc
-- Referral
ReferredAtDateKey -> FK to Date Dimension Table
PriorityKey -> FK to Priority Dimension Table
SpecialtyKey -> FK to Specialty Dimension Table
etc
-- Waiting List
AddedToListDateKey -> FK to Date Dimension Table
RemovedFromListDateKey -> FK to Date Dimension Table
StatusKey -> FK to Waiting List Status Table
Position -> int
etc
)
As you can see I am attempting to keep to the Star schema here as I am including the Foreign Keys/Relationships to Dimension tables for related objects e.g. FactReferral has all of the FactPatient relationships.
Is this the right way to model this? Or should I be using a Snowflake schema with FactReferral just having a relationship to FactPatient?
Should I create an extra denormalized Dimension for Patient with no relationships and then create a relationship between it and FactReferral? e.g.
DimPatient (
Key -> Surrogate Key
PatientId -> Source System Id
Name -> Text
Age-> int
Nationality -> Text
DateOfBirth -> Date
GenderKey -> Text
etc.
)
FactReferral (
Key -> Surrogate Key
ReferralId -> Source System Id
-- Patient
PatientKey -> FK to Patient Dimension Table
-- Referral
ReferredAtDateKey -> FK to Date Dimension Table
PriorityKey -> FK to Priority Dimension Table
SpecialtyKey -> FK to Specialty Dimension Table
etc
)
Ultimately Im not really sure how to model the one-to-many relationship tree. There are other tables that are related to Referral such as Assessment and Attendance that I have excluded from my description but I have the same problem with.
Any help or suggestions would be most welcome.
Thanks
http://www.sqlservercentral.com/Forums/Topic1728036-17-1.aspx
http://www.sqlservercentral.com/Forums/FindPost1728079.aspx
Answer provided by PB_BI
I don't think that you need a "FactPatient" table in your underlying
data since it looks like it's entirely dimensional. Rather, when it
comes to creating your cube, use the Patient dimension table to create
a measure group that has a factual relationship to the patient
dimension (for counts and such). Then your FactReferral and
FactWaitingList tables will only need to have 1 foreign key to the
Patient dimension (and not all of the patient-specific ones such as
NationalityKey etc.).
I followed the advice and created a denormalized view DimPatients and added this to my data source view. iwas then able to add a relationship to this from FactReferral -> PatientKey.
After this I created a Dimension based on the DimPatients View and was able to add all of the Columns in DimPatients as Attributes for the dimension. This made them Queryable.
The last thing I did was add a Measure Group for the DimPatient dimension which enabled me to perform Queries against the Patient data
Hope this helps someone else some day
Matt
Due to the Nature of the Question , searching for similar questions or articles is quite difficult because keywords have a wide range of meaning. So if there is a similar question, pardon me.
The Problem.
(Simplified)
I have a table of users.(Table User)
Each user Has his own assets (Table Asset Foreign key to user Id)
2 Users can be cooperators. Each user selects the assets he wants to share with the other. For use in this cooperation a Shared Group Is created containing the assets of user1 and user2 .(Table Group FK CooperationId) (Join Table Asset In group)(Table UserCooperation)
And now the tricky part.
In some occasions the user might want to Share All of his assets with a user.In order to avoid adding every time a new asset to the group manually we need a solution.
Possible Approaches. (ordered by personal preference, with queering performance in mind).
Having an Extra Table (All assets of user in group). So the
query will first check if the user added all his assets in the group
and skip querying by each asset id, but instead by userId.
Having 2 bool Flags on the Cooperation or Group Table indicating if one user is sharing all his assets with the other and not a group. The query will first read this and if true it will skip the group logic and will just query by user id.
Keep also 2 bool Flags on the sharing Table but to indicate that upon creation any asset has to be included in the Asset in Group table. So the business logic will handle inserting each new asset on that group. Query logic will not change on this occasion
Alternate Structure.
Instead of having a shared group for the cooperation, each user will have his own group and join the cooperation with his group. (Although a group has no meaning without a cooperation and the All In Group problem remains the same.)
One scheme you might consider is to define an Asset Class which could be a direct Asset or Asset Group. An Asset Group would have access to one or more Assets. So a user can share with another user just an asset or an asset class which would consist of some or all of their assets.
create table AssetClasses(
ID int not null auto incrementing primary key,
Type char( 1 ) check( Type in( 'A', 'G' )),
...,
constraint UQ_AssetClass_IDType unique( ID, Type )
);
create table Assets(
ID int not null primary key,
ClassType char( 1 ) check( ClassType = 'A' ),
...,
constraint FK_Assets_AssetClass foreign key( ID, ClassType )
references AssetClasses( ID, Type )
);
create table AssetGroups(
ID int not null primary key,
ClassType char( 1 ) check( ClassType = 'G' ),
...,
constraint FK_AssetGroups_AssetClass foreign key( ID, ClassType )
references AssetClasses( ID, Type )
);
There would be a many-to-many intersection table between AssetGroups and Assets allowing an asset to be accessible by many groups and a group to have access to many assets. There would also be an intersection table between Users and AssetClasses so you can share assets (either directly to an Asset or indirectly through an AssetGroup) to users.
This might seem convoluted, and it is a bit, but it gives you everything you asked for. And it is easily extensible -- I soon realized that owner of an asset would have to part of the asset data. As the owner would apply to both an asset and to an asset group, it would go into the AssetClasses table:
OwnerID int not null,
constraint FK_AssetClass_Owner foreign key( OwnerID )
references Users( ID )
Any attribute that applied only to an Asset or only to an Asset Group would go in the appropriate subtable.
I have the following SQL Table:
Table: dbo.Document
_________________________________________________
docID bigint (PK: required)
docTypeID bigint (required)
UploadName varchar(500) (required)
FileSize bigint (required)
DateUploaded datetimeoffset(7) (required)
tbl_userID bigint (nullable)
tbl_orgID bigint (nullable)
tbl_clientID bigint (nullable)
tbl_contactID bigint (nullable)
tbl_transactID bigint (nullable)
This Table stores uploaded documents.
Documents can be uploaded for various entities:
Users
Organizations
Clients
Contacts
Transactions
This one table stores those uploaded documents and links it to the relevant entity. It structure allows me to add the ability to upload documents to other table later on by just adding a foreign key to the Document table.
I made all the foreign keys "sparse" columns to save on space as only 1 of those columns will have a value.
Important rule: Must link to 1 table exactly. Cannot link to no table, cannot link to more than 1 table.
How do I ensure this at the database level.
I was thinking of using a check constraint - but the syntax of that might get complex (what if we uploaded documents for 20 different tables).
Can someone recommend a solution please.
I have following entities in my database:
Folder
Set
Group
Item
An Item is related to only one Group. However A group can belong to a folder or set which in turn can belong to either folder or set.
Something like this
Item1->Group1
Group1->Folder1->Folder2
Group2->Set1->Folder3
I am trying to map this to relational database in SQL server.
This is how I am mapping currently
Separate tables for each
1. Folder
2. Set
3. Group
4. Item
Item table will have ParentId as Group ID
However I will have one more Table ParentChildMapping which will have
ChildID ParentID (either of them can map to any of FolderID, SetID or GroupID)
Is this a good approach or is there any better approach?
Thanks,
You should consider an entity-subtyping approach for Folder/Set/Group and use a recursive one-to-many relationship to record the parent/child relationship at the entity-supertype level.
This might look something like this:
Table: Container (super-type)
- ContainerID PK
- ParentContainerID NULL FK (to self)
Table: Folder (subtype)
- ContainerID PK FK
- (other folder columns)
Table: Set (subtype)
- ContainerID PK FK
- (other set columns)
Table: Group (subtype)
- ContainerID PK FK
- (other group columns)
Table: Item
- ItemID
- (other item columns)
- ContainerID (FK to GROUP)
I need to define a one-to-one relationship, and can't seem to find the proper way of doing it in SQL Server.
Why a one-to-one relationship you ask?
I am using WCF as a DAL (Linq) and I have a table containing a BLOB column. The BLOB hardly ever changes and it would be a waste of bandwidth to transfer it across every time a query is made.
I had a look at this solution, and though it seems like a great idea, I can just see Linq having a little hissy fit when trying to implement this approach.
Any ideas?
One-to-one is actually frequently used in super-type/subtype relationship. In the child table, the primary key also serves as the foreign key to the parent table. Here is an example:
CREATE TABLE Organization
(
ID int PRIMARY KEY,
Name varchar(200),
Address varchar(200),
Phone varchar(12)
)
GO
CREATE TABLE Customer
(
ID int PRIMARY KEY,
AccountManager varchar(100)
)
GO
ALTER TABLE Customer
ADD FOREIGN KEY (ID) REFERENCES Organization(ID)
ON DELETE CASCADE
ON UPDATE CASCADE
GO
Why not make the foreign key of each table unique?
there is no such thing as an explicit one-to-one relationship.
But, by the fact that tbl1.id and tbl2.id are primary keys and tbl2.id is a foreign key referenceing tbl1.id, you have created an implicit 1:0..1 relationship.
Put 1:1 related items into the same row in the same table. That's where "relation" in "relational database" comes from - related things go into the same row.
If you want to reduce size of data traveling over the wire consider either projecting only the needed columns:
SELECT c1, c2, c3 FROM t1
or create a view that only projects relevant columns and use that view when needed:
CREATE VIEW V1 AS SELECT c1, c2, c3 FROM t1
SELECT * FROM t1
UPDATE v1 SET c1=5 WHERE c2=7
Note that BLOBs are stored off-row in SQL Server so you are not saving much disk IO by vertically-partitioning your data. If these were non-BLOB columns you may benefit form vertical partitioning as you described because you will do less disk IO to scan the base table.
How about this. Link the primary key in the first table to the primary key in the second table.
Tab1.ID (PK) <-> Tab2.ID (PK)
My problem was I have a 2 stage process with mandatory fields in both. The whole process could be classed as one episode (put in the same table) but there is an initial stage and final stage.
In my opinion, a better solution for not reading the BLOB with the LINQ query would be to create a view on the table that contains all the column except for the BLOB ones.
You can then create an EF entity based on the view.