Can multiple relationship occur between two entities? - sql

I have following two entities, where a person address is kept in a separate table because a person can have multiple addresses.
The mailing address however is one of the multiple addresses stored in address table, which is to be referred in person table.
Can following relationship exist?

The answer to your direct question is "Yes". However, you cannot declare the model only using create table because:
Declaring the foreign key address.person_id requires that the person table already exist.
Declaring the foreign key person.mailing_address requires that the address table already exist.
Hence, to implement the model, you need to use alter table to add one or both of the constraints after both tables are created.
Is this the model you want? One feature of an address is that multiple people can have the same address. Your model does not allow that. To handle this, you would typically have three tables:
Person
Address
PersonAddress
The third table has one row for each person/address pair. It can also have other information such as:
Type ("mailing" versus other types)
Effective and end dates.
Perhaps other information.
If you want to guarantee uniqueness of the "mailing" address in such a model, many databases support filtered unique indexes, to ensure there are no duplicate mailing addresses.

I'm not sure why you have person_id as an fk on address but that doesn't look correct. There are lots of correct ways to model this and the best one for you will depend on you particular circumstances - but a couple of options are:
If you know all the types of addresses there can be then add multiple address fk fields to the person e.g. billing address, shipping address, etc. This makes querying quick and simple but is inflexible: adding a new address type in the future is relatively complex to implement
Add an intersection table with fks for person and address and an address type field. This has a slight overhead when it comes to querying but has the advantage if being very flexible: adding a new address type is trivial

Related

SQL Join to either table, Best way or alternative design

I am designing a database for a system and I came up with the following three tables
My problem is that an Address can belong to either a Person or a Company (or other things in the future) So how do I model this?
I discarded putting the address information in both tables (Person
and Company) because of it would be repeated
I thought of adding two columns (PersonId and CompanyId) to the
Address table and keep one of them null, but then I will need to add
one column for every future relation like this that appears (for
example an asset can have an address where its located at)
The last option that occur to me was to create two columns, one
called Type and other Id, so a pair of values would represent a
single record in the target table, for example: Type=Person,Id=5 and
Type=Company,Id=9 this way I can Join the right table using the type
and it will only be two columns no matter how many tables relate to
this table. But I cannot have constraints which reduce data integrity
I don't know if I am designing this properly. I think this should be a common issue (I've faced it at least three times during this small design in objects like Contact information, etc...) But I could not find many information or examples that would resemble mine.
Thanks for any guidance that you can give me
There are several basic approaches you could take, depending on how much you want to future proof your system.
In general, Has-One relationships are modeled by a foreign key on the owning entity, pointing to the primary key on the owned entity. So you would have an AddressId on both Company and Person,which would be a foreign key to Address.Id. The complexity in your case is how to handle the fact that a person can have multiple addresses. If you are 100% sure that there will only ever be a home and work address, you could put two foreign key columns on Person, but this becomes a big problem if there's a third, fourth, fifth etc. address. The other option is to create a join table, PersonAddress, with three columns a PersonId an AddressId and a AddressType, to indicate whether its a home work or whatever address.

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.

Is it a good practice to store different data in the same column - SQL

I currently have a Users table which has the following columns:
UserId
Address
Currently we are storing the IP Address in the Address column. Moving forward, we need to store say a MAC address. Is it a good practice to store both of them in the same column (both are varchar) and have another column indicating what type it is typeOfAddress int with a 1 or 2 indicating type of address. Or should I create a separate nullable column (and change the existing one to nullable as well)
No it isn't good practice. One of the first things I was told several decades ago was 'a computer field should not be used for more than one purpose'. Otherwise you have in principle no way of knowing what it means, unless you have another indicator field, which you may as well use for the other value type, and you are introducing the entirely unnecessary risk of misinterpretation.
Absolutely create a separate nullable column. It will make writing all your future SQL on this table much easier, and keep everything much more maintainable overall.
Well, based on the information given, it depends.
Would a user have both an IP address and a MAC address? If they do, you would need to put these records in a separate table with a foreign key relationship to the user record.
What about retrieval? Do these values often need to be retrieved when retrieving data about a user? If they do, it may make sense to store them in the same table and avoid the table join each time.
I'd be inclined to have two separate columns, one for IpAddress and another for MacAddress. This way it is clear what data is in what column without the need to lookup against another column to figure it out.
Recommended is this structure:
UserId
AddressType
Address
because it is in 3rd NF.
The disadvantages of simply using multiple columns in a single table are these:
The need to remember to "null-handle" whenever filtering on Address
Over time, the paradigm may expand beyond sense as new address types are addded; but a conversion becomes too costly to contemplate.
An AddressType table should be added with a FK relationship to prevent accidental entry of AddressTypes that look valid, but aren't.
Best of all, theoretically, would be a separate table for each AddressType, linked on UserId to the user table; but that really does look like overkill for the problem as presented.
If you don't think you're going to be adding a bunch more different types of addresses, my preference would be for having two columns. I think it's simpler conceptually and simpler to query. But if you think you're going to be adding more types of "addresses" (whatever that may be), having 5 or 6 different columns may not be ideal. In that case, I'd go with one address column and one address_type column, and create a junction table that defines the address types.
Instead of making new columns, create a new table Address and AddressType, link to those:
Users
foreign key address_id
Address
id
value (varchar)
foreign key adress_type_id
AddressType
id
name (varchar)
Might be overkill, but it's good normalisation practice

database optimization issue

i have a table Students which contains the following colums:
Id,FirstName,LastName,Adress.
The colum Adress will contain just the street adress.
the question is: will it be better for the database optimization to isolate the column Adress in a different table?
Yes. If you seperate it into another table, you can have more than one address per person. If you seperate it to two different tables, an Address table and a StudentAddress table to map the two together, you can make sure that a single address is shared between people or even track a history of addresses for one person. Further, in a seperate table you can break the address down into columns so that you can easily search by City or Province or Country.
You can't do any of that putting an Address into a single column with the Student table.
It depends on how you are going to treat that Address. If you will need to treat it as different entity, i.e. link single address to several Students or vice versa e.t.c., then you should do normalization.
If address is only attribute of entity student then leave it as is.
For full proper data structures to manage addresses: THe Data Model Ressource BOok, Volume 1. It is a LOT more complicate to get right than you think.

Design Pattern required for database schema with two classes both composing a third class

Consider a system which has classes for both letters and people; both of these classes compose an address. When designing a database for the system it seems sensible to have a separate schema for the address but this leads to an issue; I don't know how to have a foreign key in the address table cleanly identify what it belongs to because the foreign key could identify either a letter or a person. Further more I expect that further classes will be added which will also compose an address.
I would be grateful for design patterns addressing this kind of design point.
Best Regards
I don't know how to have a foreign key
in the address table cleanly identify
what it belongs to because the foreign
key could identify either a letter or
a person.
It sounds like you have got that the wrong way around. There would be no foreign key in the address table; rather, the letters table would have a foreign key referencing the address table and the persons table would also have a foreign key referencing the address table.
In SQL, the REFERENTIAL_CONSTRAINTS view in the Information Schema catalog will tell you which tables are referencing the address table.
In our shop we regularly debate whether an address should be modelled as an entity in its own right. The problem with treating an address as an entity is that there is no reliable key beyond the attributes themselves (postal code, house name or number, etc) and many variations can identify the same address (I can write my home address twenty different ways). Then you need to consider post office boxes, care of addresses, Santa Claus, etc. And the Big Question: do you allow an address to be amended? If someone moves house, do they keep the same address entity with amended attributes (that way all linked entities get the address change) or do you lock-down addresses' attributes and force the creation of a new address entity then relink all the referencing addresses to the new one (and do you delete the now-orphaned address entity and if yes then why did you bother to replace it...?) But your application still needs to allow an address to be amended in case the post office changes it in real life, but how to you prevent this ability from being misused i.e. using it for aforementioned illegal house moves? You can use a webservice to scrub your address data so that is is correct but an external system way have less clean data and therefore you can't get your address entities to match anymore...?
I like to keep it simple: an address is a single attribute being the plaintext you must put on an item of mail for it to be delivered by the post office to the addressable entity in question; it is not an entity in its own right because it lacks an identifier. For practical reasons (e.g. being able to print it on an address label), this single attibute is usually split into subatomic elements (address_line_1, address_line_2, ... postal_code, whatever).
Because most SQL products lack support for domains, I have no problem duplicating the column names, data types, constraints, etc between for each table that models an addressable entity.
Surely the foreign keys should be from the Letter and People tables referencing the primary key on the Address table?
So, the Letter table contains an AddressId column referencing the Id on the Address table, as does the Person table, and any future classes which compose an address.
If Letters and Persons compose multiple addresses, then intermediate link tables will be required.