One-To-One reference side - sql

I'm not sure if I named this question right.
Imagine that there is two tables: one that represents Users and another represents Addresses.
One user can have only one address:
CREATE TABLE User (
id INT NOT NULL,
full_name VARCHAR(255),
PRIMARY KEY(id)
);
CREATE TABLE Address (
id INT AUTO_INCREMENT NOT NULL,
address_line_1 VARCHAR(255),
address_line_2 VARCHAR(255),
PRIMARY KEY(id)
);
The question is: where is the right place to put foreign key reference to? Should I put a reference column into the User table by creating "address_id" column that references to Address.id? Or should I put user_id column into the Address table that references to User.id?

When you have 1-1 association, you need to ask yourself why is it there in the first place? Most of the times it indicate that the design is incomplete or inaccurate. Sometimes 1-1 is correct, don't get me wrong, but you have to justify its existence.
Having said that,in your case, chances are you will be accessing the user as the main table. Your end-users may be looking for user profiles by userid,then drill down or navigate to more profile information such as the address. If this is the case, the FK would belong to the address table. However, if your business is such that your end-user will be browsing address information primarily then drill down to user information then the FK would belong to the user table.
Another thing you need to complete here is whether the FK is mandatory or optional (Not Null or Nullable) since this would affect RI. What happens if I delete a user? Should the corresponding address go away?

Here there is chance of getting more number of users in same address hence placing the Foreign key in address table would be my choice.

Related

Multiple tables for a single foreign key

I'm currently making a database for my java web app for Tourism.
Only register user can book a tour but can take along several people.
For this, I separate into User table and Guest table, each with its own primary key.
Everything is set so far, but when it comes to making my BookRoomDetail table, I have to fill in which person for which slot in the room. the problem arises when both register user and guest can fill this slot, and they're from 2 different tables.
How do I set the foreign key(or anything else) for this?
As I got your problem, you can add one more field for MainUser in your tblBookRoom Detail as a foreign key. And whenever any user books room you can add his/her primary key and guest primary key in forwhom field.
**tblBookRoomDetail**
ID (Primary key Of Table)
RoomId
For Whom (For MainUser or Guest)
MainUser (MainUser Primary Key Who is doing this reservation)
Slot
FromDate
ToDate
BookId
This is not possible to insert two different primary key value in a column of other table, if you have relation in them.
You can do this without the making the relation in them.
But it's not a good process because if the both key value same in this case you can't identify the actual.
If you want to achieve this goal then you should have a table tblAllUsers which primary key is also primary key of the tblGuest and tblUser and then you can make relation to tblBookRoomDetail table direct to tblAllUsers. In this case you can differentiate the Guest user or Registered Users.
or
Can Create the two different columns in tblBookRoomDetail, one for Guest user and second for Registered user.

Sql one foreign key for different tables

First of all, I do realize that there are plenty of questions regarding this problem and there is a good chance that I already know one of the answers, but after I've tried a couple of them, none of them worked for me.
In my application I am handling communication between user and customer. Both users and customers can have multiple e-mail addresses. Also, both users and customers can be assigned to multiple conversations at the same time. After user or customer sends an e-mail message, system receives information about that and creates a ConversationMessage with basic info about the message and EmailMessage with specific data (subject, FROM, TO etc.).
Right now, fields FROM and TO are just varchar fields with e-mail addresses. I would like to change it so that FROM and TO fields are foreign keys. I was planning to create an EmailAddresses table that would store basic info about the address and UserEmailAddresses and ContactPersonEmailAddresses tables with specific info about address (like host, port etc.), but I realized that EmailAddresses table would contain just an Id. Is it a good approach? Am I missing something?
Are there any better solutions to this kind of problem?
Thank you for any help!
There are numerable issues with the design but let's limit the discussion to the email addresses. You store the addresses in two tables. This, unsurprisingly, is causing problems.
An email address is an entity. Store them in a table. Anywhere a single address is needed, place a FK to the one address table there. Where multiple addresses is or may be needed, place an intersection table there.
create table EmailAddresses(
ID int auto_generating primary key,
Addr varchar not null unique,
Active bool
);
Are such fields as Login, Port, etc. really attributes of an email address? Maybe you could clarify those if you would.
Then the tables UserEmailAddresses and ContactEmailAddresses would be intersection tables and look something like this:
create table [User|Contact]EmailAddresses(
UserID int not null references [Users|Contacts]( ID )],
AddrID int not null references EmailAddresses( ID )
);
As an email message can only have one "From" value, that would be in the EmailMessages row as it is now except it can now be a FK to the one address table. A message may have one or many "To" values so that would be implemented also as an intersection table:
create table EmailTo(
EmailID int not null references EmailMessages( ID )],
ToID int not null references EmailAddresses( ID ),
ToType enum( To, CC, BCC )
);
There are probably other requirements that would require some constraints on any or all of the tables above but those depend on your usage. For example, even though email applications allow the same address to exist more than once in a From list, you may want to catch and restrict such occurrences. This would be implemented by a unique constraint on (EmailID, ToID)
Possible extensions would be the addition of email lists which themselves contain a group of addresses. That would require the EmailAddresses table to split but because all addresses are now located in one table, such a redesign would certainly be easier that having them located in two tables.

How do I create a table model in SQL?

Let's say I've 3 tables: enterprise, users, houses.
Everyone needs an address. What should I do?
Create a table address for everyone?
Create one unique table address?
Assuming that the first is "more" correct (cache, fragmentation, size, ...), how should I write it in plain SQL?
How do I create a "model" of the table address, and use it in custom tables (e.g. enterprise_address)?
* So when I change one field in the model, it gets replicated.
It appears you need every user to have an address. You have multiple ways to solve it.
Handle it in UI
Your users table will be just information about users (on address info here)
Create addresses table with addressid as primary key
Create many-to-many table/junction table called user_addresses that brings userid and addressid together
Ensure that your UI mandates address for each user
Tables
create table addresses (addressid int not null PK, line1, line2, city ...);
create table users (userid int not null PK, username, ...);
create table user_addresses (user_addressid int, userid int, addressid int, UK userid + addressid, FK to users, FK to addresses);
This allows a user to have multiple addresses. You have the flexibility of marking which one is primary.
Handle it in DB (and UI)
create table addresses (addressid int not null PK, ....);
create table users (userid int not null PK, username varchar(20), ..., addressid int not null, FK to addresses);
This allows one address per user.
and handle it also on the UI to ensure that address is supplied. Enter address into addresses first and then into users (make it an atomic process; use transactions!)
You can start with one these methods and analyze what your business needs are. Work with your DBA, if you have one, to see what their experience says about the business and previous DB designs similar to this.
Just from the three given tables I would assume that address is something you would want to put in either Houses or Users.
Depending on how much detail you want to keep track of in the Address it could be work making a separate table but there are a number of ways to go about this and the correct method depends solely on what you are trying to achieve.
Without knowing any of the required information all I can really advise is that you should aim to store the addresses as unique values. Once you have this you can assign each address to any other table you wish using a Foreign Key.
If you want to store multiple fields for the address then you will require a seperate table, if a single field will do then it could just as easily be added to the person or houses table.
One thing that would make a major difference to which way you would want to do this is the relationship between address and your other entities. For example if a user can have many addresses then you cant make it a part of the user table, and if an address can have multiple users assigned to it then it cant use a FK to represent its relationship to the users table.
One way you can do this is to make a relational table. So you make addresses and users seperate tables then have another table with just an id(pk) and 2 fks linking it to each of the other tables. This way you can have a many to many relationship if you wish.
First question: how many addresses per enterprise/user/house? If there are multiple addresses per entity, that leads you to want a separate address table, possibly with an address type.
Examples of multiple address situations:
Multiple locations
Ship-to addresses
Physical vs. PO Box
If you are going to assert that an entity can only have one address, then you probably prefer making the address part of the entity row, for simplicity. However, there can be reasons not to do that; for example, table width (number of columns in the table).
If you have multiple addresses per entity, typically you will use a foreign key. The entity should have an abstract key: some kind of ID. This will either be an integer or, in SQL Server, it could be a uniqueidentifier. The entity ID will be part of the key for the address.
Ok, I found the answer to postgresql: use INHERITS
e.g. CREATE TABLE name () INHERITS (table_model)
Thank you all for the answers.

Access add new rows

I have database and when I try to add new row it gives error of Referential Integrity. It says the data can not be added because of referential integrity constraint and foreign key data should be in primary key table. Problem is when I try to add data in Branch table it requires managerNo and in Manager table it requires technicianNo and in Technician table it requires customerNo.
So,
Let's start with the Branch table.
[Branch]
brandID,
buildingnumber
streetname
city
postcode
phone
fax
[Branch_Technicians]
branchID
technicianID
[Technician]
technicianID
name
housenumber
streetname
city
postcode
phonenumber
So initially, your relationship was ONE BRANCH CAN HAVE MANY TECHNICIANS which is correct, however, what you've got to understand is that ONE TECHNICIAN CAN WORK AT MANY BRANCHES, therefore creating a many to many relationship, to resolve this I have created an extra table called Branch_Technicians this is called an Associative Entity.
I won't complete all of it, I'll let you work out the rest, as I do not have the time to construct an entire database. I could go into greater depth. But this is how I'd do it.. work with this (that's what I'd recommend)
Hope this helps,
Sohail.

Creating a table with a field (with a foreign key) which can reference many tables and maintain referencial integrity?

what is the best way of creating a table which can hold a key to a lot of other tables?
As far as I know I have two options:
1) I create a table with a lot of foreign key fields
2) I create two fields, one which indicates the referenced table and another field which holds the primary key of that table.
The latter has a lot of issues due to the fact there's no way to maintain referential integrity (because there's no foreign key to each table).
Besides a link to this table I want to add a description so I can show all notifications in a grid. By clicking a line in the grid I want to open the corresponding program and fix the issue in that program.
It's a bit hard to explain, perhaps this example explains better:
I need to create a system which handles task/notes/notifications for every program in our business application. We have invoices, sales-orders, deliveries, production-orders, etc
Our software detects that something is wrong which any of these. For instance, if the profits on a sales-order are not high enough the order can't be validated automatically. In this case I want to create a notification for the sales-manager so that he can check out what's wrong with the sales-order.
FYI: Iam using Sybase SQL Anywhere 12.
Does it make any sense?
This can be solved in reverse way. Lets say that you have table Alerts where you are going to put all kind of alerts about bad things happened elsewhere. You may reference this table from ALL other tables in your system and create non-mandatory relationship from them. In short it may look like (i'm using MSSQL syntax):
create table Alerts(
ID int not null identity,
SomeInfoAboutTheProblem varchar(255),
constraint PK_Alerts primary key (ID)
)
create table Invoices(
ID....
AlertID int NULL,
....
constraint FK_Invoices2Alerts foreign key (AlertID) references Alerts(ID)
)
In case you cannot modify your tables with business information you may create "extention" table for Alerts that may store some specific problem information and actual reference to the problematic record. For example:
create table Alerts(
ID int not null identity,
SomeInfoAboutTheProblem varchar(255),
constraint PK_Alerts primary key (ID)
)
create table Alerts_for_Invoices(
AlertID int NOT NULL,
InvoiceID int NOT NULL,
SomeAdditionalInvoiceProblemInfo ....,
constraint FK_Alerts_for_Invoices2Alerts foreign key (AlertID) references(ID),
constraint FK_Alerts_for_Invoices2Invoices foreign key (InvoiceID) references Invoices(ID)
)
To show list of problems you may just select general information from Alerts table while opening the dialog you may select all appropriate information regading the problem.