I have two database tables "Users" and "Transactions" with many to many relationship between them. I have created a Junction Model which will have two foreign key columns (UserId, TransactionId) and will keep track of the associations. The Transaction table has two columns where I keep track of who the sender is and who the recipient is (senderAccount, recipientAccount).
Question 1: since each Transaction belongs to two users which are the sender and recipient, do I also need to specify both senderId and recipientId inside the junction model instead of just userId?
Note: my confusion is from the two foreign key columns(UserId and TransactionId) inside the junction model. I understand that there is only one transaction and you can reference that transaction by its id in the junction model, but each transaction is also owned by two users (sender and recipient) shouldn't we reference both of the users inside the junction model?
Question 2: if my analogy up here is correct, how would you reference both senderId and recipientId inside the junction model?
Question 3: if my analogy up here is incorrect, please help me understand how you would go about referencing both users in the junction model.
Users table
id | username |
—--+----------+
1 | ijiej33 |
Transactions table
id | transactionId | senderAccount | recipientAccount | Amount |
—--+---------------+---------------+------------------+--------+
1 | ijiej33 | A | B | 100 |
userTransaction table (junction model)
userId | TransactionId |
-------+---------------+
| |
As I explained as a comment in your question from yesterday, you do not have a many-to-many relationship between transactions and users. You have two many-to-one relationships from transactions to users. You therefore do not need a join table.
Model it thus:
create table users (
user_id serial primary key,
user_name text not null unique
);
create table transaction (
transaction_id serial primary key,
sender_account int not null references users(user_id),
recipient_account int not null references users(user_id),
amount numeric
);
Suppose I have a table with following attributes
order id
item id
item quantity
item unit price
item payment
where "item payment = item unit price x item quantity".
Let us simplify the situation, and assume each order has any quantity of just one item id, and different orders may have the same item id.
What is the primary key, "order id", "order id" and "item id", or
something else?
How can it be normalized into 3NF?
Here is a solution that I am thinking:
a table with order id (primary key), item id, item quantity, and item payment
a table with item id (primary key, and foreign key to the previous table), and item unit price.
Continue with the tentative solution I gave in part 2. In the first table, for each item id, item payment is
proportional to item quantity. If the primary key of the first table
is order id, item payment depends on non-primary-key attribute item quantity, which
violates 3NF requirements of no transitivity.
Shall I split the first table into:
a table with order id (primary key), and item id
a table with item id (primary key, and foreign key to the table before), item quantity, and item payment
or into:
a table with order id (primary key) and item id
a table with item unit price (primary key, and foreign key to the original second table), item quantity, and item payment?
Thanks.
You should probably have a table with OrderID as the primary key. This is because you're likely to have attributes that have non-trivial Functional Dependencies on the order (eg. order_date, order_status, CustomerID) that are not dependent on a line in the order.
You should also again have a table where ItemID is the primary key. Again it will have attributes that would have a functional dependencies on ItemID (e.g. description, price, etc)
Finally you'd have a third table. This table would have Foreign keys to Order and Item. These keys would represent a candidate compound key. You could either use this or create a surrogate Primary Key OrderItemID. If you do create a surrogate key I would still be sure to create a unique key (OrderID, Item).
+----------------+ +----------------+
| OrderID | | ItemID |
+----------------+ +----------------+
| CustomerID | | Description |
| OrderDate | | Price |
| Status | +----------------+
| Payment | |
+----------------+ |
| |
| |
| +---------------------+ |
| | OrderItemID | |
| +---------------------+ |
+-------+ OrderID FK U1 +---+
| ItemID FK U1 |
| Quantity |
+---------------------+
Let's not talk of IDs at the start...
There are orders. Orders usually have an order number that you can have printed on the invoice etc. An order has an order date, and a supplier when this is about orders you place with your suppliers or a client when this is about orders your clients place with you.
There are items that can be ordered. Items have an item number, e.g. a GTN (Global Trade Number). Items have a name and a price or even a price list for different dates, different customers, whatever.
An order can contain several items usually, e.g. 5 pieces of item A and 10 pieces of item B. These are order positions containing item, amount and price.
That could be the tables (primary key bold, unique columns italic):
client (client_number, client_name)
item (item_number, item_name, price)
order (order_number, order_date, client_number)
order_position (order_number, item_number, amount, price)
You would not store single price and amount and total price, as this would be redundant. Avoid redundancy in a database, for this can result in a lot of problems.
You can use technical IDs in your tables. You can make these the tables' primary keys, but you'll have to store all data mentioned above still, and what was a primary key before is then a column or set of columns that is defined non-nullable and unique which is literally the same as a primary key:
Tables (primary key bold, unique columns italic):
client (client_id, client_number, client_name)
item (item_id, item_number, item_name, price)
order (order_id, order_number, order_date, client_number)
order_position (order_position_id, order_id + item_id, amount, price)
This looks like an order line. Typically you'd have a primary key of order id and order line number. item id should be a foreign key from your items table, which should have a price, but unless you never give discounts, your order line should have a price, too.
Having the amount paid against an order line is OK, if you allow partial payments and want to track it at that level.
Guessing via your names & common sense, a 3NF decomposition of your table is
-- order order_id requests item item_id in quantity item_quantity
order_has_item_in_quantity(order_id, item_id, item_quantity)
-- item item_id has unit price item_unit_price
item_has_unit_price(item_id, item_unit_price)
-- some order requests some item in quantity item_quantity
-- and that item has unit price item_unit_price
-- and item_unit_price * item_quantity = item_payment
unit_price_and_quantity_has_payment(item_unit_price, item_quantity, item_payment)
However, if you already have access to a multiplication table (which is a constant), which you do in an SQL query (via operator *), then your design doesn't need column item_payment in the original and consequently its decomposition doesn't have table unit_price_and_quantity_has_payment--it is a certain restriction of the multiplication table; it is a certain function of the multiplication table & the first two tables.
As to my guesses, and relevant CKs (candidate keys), and justification: Normalization uses FDs (functional depencies), and you haven't mentioned them, so it doesn't seem like you have even a basic idea of what you are doing. So right now your question is just asking for some chapter(s) of some textbook(s). That's too broad--read some. None of the answers here correctly explain or reference how to do this--they are useless for the next case & unjustifiable for this case. Moreover they are all guessing at your specification but should be asking you for appropriate info.
I have two tables I want to join in SQL Server.
One houses call data and has a unique id Login_ID. This table does not contain the employees name.
The other table does not have a unique id for employees.
What I need to do is join these two tables so I can see call data and ticket data simultaneously by employee.
Unfortunately, there is no correlating column for Login_ID in the ticket table to link employee data.
Example of call data table:
Login_ID | Calls | CallTime | Date |
00000001 | 34 | 349874 | 030317 |
Example of ticket table:
Name | Ticket_Num | Date |
Some Emp | 5456465434 | 030317 |
So what happens is: anytime someone changes their name, they basically have a new ID in this table. It's awful.
I only need the data from around 18 employees.
My question is: how can I associate the Login_ID with the ticket table?
Hopefully I made this clear enough!
You should to store the association using what is known as a Foreign Key. This will ensure the integrity of the relationships between your data and can help optimize your queries when you are trying to pull associated data from different tables.
A FOREIGN KEY is a key used to link two tables together.
A FOREIGN KEY is a field (or collection of fields) in one table that
refers to the PRIMARY KEY in another table.
The table containing the foreign key is called the child table, and
the table containing the candidate key is called the referenced or
parent table.
You get query associated date using a join.
If you have a 1:1 relationship you add Login_ID as a field to your ticket table and you can join your table on Login.Login_ID = Tickets.Login_Id.
Alter Table Tickets
Add Login_ID int not null Constraint "FK_Tickets_LoginId" References Tickets(Login_Id)
// USAGE:
Select * from Logins Join Tickets on Logins.Login_ID=Tickets.Login_Id where Login_ID=#LoginId
If you can't modify either table then you can create a new table, perhaps Logins2Tickets which will contain two fields Login_ID and Ticket_Num
You can then join your Logins to Logins2Tickets on Login.Login_ID = Tickets.Login_Id and join Logins2Tickets to Tickets on Logins2Tickets.Ticket_Num = Tickets.Ticket_Num
Create Table Logins2Tickets
(
Login_ID int not null constraint "FK_Logins2Tickets_Login_ID" References Logins(Login_Id)
Ticket_Num bigint not null constraint "FK_Logins2Tickets_Ticket_Num" References Tickets(_Login_ID)
)
// USAGE:
Select *
From
Logins l Join Logins2Tickets lt
on l.Login_ID=lt.Login_ID
Join Tickets t
on lt.Ticket_Num=t.Ticket_Num
WHERE Login_ID=#LoginId
INSERT INTO customers (ID, NAME, AGE, ADDRESS, SALARY)
VALUES(3, 'sin', 21, 'bangalore', 10000);
INSERT INTO orders (orderid, orderno)
VALUES (3, 21);
Here ID is the primary key in the customer table, orderid is the primary key in the orders table.
I would like to know whether it is mandatory to add id as foreign key in orders table for performing SQL join?
It is not necessary to establish a foreign key in order to perform an inner join of the customers and orders table. However, the question arises of what the significance of such a join operation would be without a foreign key.
Presumably the goal is to model some sort of relationship between customers and orders. Assuming the attributes listed comprise all of the attributes in the two tables, there is nothing establishing a relationship between customers and orders in the way the tables are defined. Adding a customerID field as a foreign key in the orders table would establish that relationship. Then, an inner join on the condition customers.ID = orders.customerID would associate the order information with the appropriate customer's information in the joined table.
My thought here that when you asking whether FK is needed or not, you accept by default that both working within the same domain, and this is not a valid assumption, in brief
The inner join is used with the reading (query) of data, whereas FK
exists to maintain the integrity of data during a different kind of operations such as insert, update and delete.
In my opinion, the correct answer should be that both FK and inner join are not relevant.
I will use the below tables to explain the difference between both
Customers
| id | name |
|:------------|---------:|
| 1 | Gabriel |
| 2 | John |
| 3 | Smith |
Orders
| order_id |customer_id|
|:-----------|---------: |
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
Inner Join,
is used during query for example according to the above, let's say you want to query all orders made by a specific customer.
select * from customers, orders
where customer.id=orders.customer_id
and customer.id=2
according to our tables, you will end up with one order number (4) for the customer (John)
Foreign Key
While the inner join used during the query, the Foreign Key is used to apply policies over the major DML operations (Insert, update and delete).
below are examples of operations that will fail for violating the FK constraint
Insert into orders(order_id,customer_id) values(5,7)
this operation will fail because no customer exists with id (7) in the Customer table, the same will apply for the update operation.
Also if the FK enabled the On delete cascade or On update cascade
this will delete or update child rows when trying to delete or update the master table, example deleting the customer Gabriel will delete orders 1,2 and 3.
I'm currently working on a SQL assignment that wants me to:
Add an index for each foreign key and an index on Company for Customer and Shipper.
I've created the 3 tables that were needed, created the foreign and primary keys, and so on. But my textbook has not mentioned anything about indices and I am at a loss as to what to do. If you have an answer, it'd be nice to know how you got to it.
The structure of the tables:
Customer
CustomerID (PK) | Company | ContactName | Phone
Order
OrderID (PK) | OrderDate | ShippedDate | ShipperID | Freight | CustomerID (FK)
Shipper
ShipperID (PK) | Company | Phone
You should be looking at the online documentation, but...
To create indexes for foreign keys:
create index Order_ShipperID on Order(ShipperID);
create index Order_CustomerID on Order(CustomerID);
To create indexes on Company for Customer and Shipper:
create index Customer_Company on Customer(Company);
create index Shipper_Company on Shipper(Company);
The names of the indexes can be anything, but I usually follow this naming convention.
BTW, the choice of name "Order" is a poor one because its a reserved word.
You can create Index on any SQL Table column. Once Indexes are created on your Table column you just have to send the Select query and you can check logically the performance of you query. You can check the next link for reference to the solution:
www.blog.mastersoftwaresolutions.com/how-do-database-indexes-work/