Store multiple ids into one column - sql-server

The main idea is to store multiple ids from areas into one column. Example
Area A id=1
Area B id=2
I want if it is possible to save into one column which area my customer can service.
Example if my customer can service both of them to store into one column, I imagine something like:
ColumnArea
1,2 //....or whatever area can service
Then I want using an SQL query to retrieve this customer if contains this id.
Select * from customers where ColumnArea=1
Is there any technique or idea making that?

You really should not do that.
Storing multiple data points in a single column is bad design.
For a detailed explanation, read Is storing a delimited list in a database column really that bad?, where you will see a lot of reasons why the answer to this question is Absolutely yes!
What you want to do in this situations is create a new table, with a relationship to the existing table. In this case, you will probably need a many-to-many relationship, since clearly one customer can service more than one area, and I'm assuming one area can be serviced from more than one customer.
A many-to-many relationship is generating by connection two tables containing the data with another table containing the connections between the data (A.K.A bridge table). All relationships directly between tables are either one-to-one or one-to-many, and the fact that there is a bridge table allows the relationship between both data tables to be a many-to-many relationship.
So the database structure you want is something like this:
Customers Table
CustomerId (Primary key)
FirstName
LastName
... Other customer related data here
Areas Table
AreaId (Primary key)
AreaName
... Other area related data here
CustomerToArea table
CustomerId
AreaId
(Note: The combination of both columns is the primary key here)
Then you can select customers for area 1 like this:
SELECT C.*
FROM Customers AS C
WHERE EXISTS
(
SELECT 1
FROM CustomerArea As CA
WHERE CA.CustomerId = C.CustomerId
AND AreaId = 1
)

Related

SQL-SERVER- get way relationship between tables

i have a big DB, and i wants to create query that i give her two name of tables and she give me the relationships between her.
for example:
in my DB i have three table:Person,SupportActitvity and ProcessesSupportActivity.
Person related to SupportActitvity , and SupportActitvity related to ProcessesSupportActivity
if i want to get the ProcessesSupportActivity for Person i write:
select *
from person
join SupportActivity on Person.PersonId=SupportActivity.PersonId
join ProcessSupportActivity on ProcessSupportActivity.SupportActivityId=SupportActivity.SupportActivityId
I want that when i write that for Person and ProcessSupportActivity he give me the relationships.
he return:
Person PersonId SupportActivity PersonId
SupportActivity SupportActivityId ProcessSupportActivity SupportActivityId
Thank you very much!!!!
to look for the shorter way, I call to dijkstra algorithm.
The graph is constructed from all tables in DB, Each table it's was a node in the graph.
and the path it's was all of the relation of table.
obviously that the graph build in signaltone אם economize runtime.
And when you want to discover a connection between two tables in the database you send the source table and destination table and get the path....
It works amazing

When one SQL table is linked to another table, is it impossible to delete the data from the database?

There are three tables linked to each other as in the diagram.
This Youtuber is using IsDeleted=0 or IsDeleted=1 column to indicate that the data in the table is deleted or not.
When one SQL table is linked to another table, is it impossible to delete the data from the database? If it is impossible, then I think its really bad. Isn't there any workarounds for completely deleting the data?
Also, maybe Facebook also does something like IsDeleted=1 and they don't let us see us our own data when we 'delete' it while they can still access our past interests. What do you think?
No, data can always be deleted from a database. There may be constraints what has to happen before the data gets deleted (permissions, foreign-key constraints, etc), but it eventually can be deleted.
A column such as that is frequently used for maintaining data history in the application. The "links" you refer to are called Foreign Key relationships and they are used to maintain integrity within relational data. The IsDeleted column in the resultset doesn't have anything to do with the FK.
Also, that column would not indicate that the table is deleted, but rather the row of data the values of the column belong to.
Well defined and static and structured arrangement of data is one of the most important things in relational databases. In the tables you show, Employee belongs to a department. Now if you delete the department, you have a broken record in the Employee table. This is why, SQL will not allow you to delete the department.
To solve this, you will need to either stop the deletion of department with message like "There are users in this department. Cannot be deleted." or remove the department id (set it to null) from the employee records which belong to this department.
There are situations, business needs where the data is to be retained for various reasons. In those cases, IsActive like flags come to rescue. The records can be filtered using them and thus are hidden on the screen. This is generally referred to as soft delete.
Actually, i think it is very good practice to do Soft Delete rather than hard delete because you can safely recover the data later. To your question you can only delete parent table data if there are no more child table data. Else you get this errror:
the delete statement conflicted with the reference constraint ...
for example in your database say you have data of employee and departments. e.g this is your department table:
ID DepartmentName
1 HR
2 marketing
and this is your employee table:
ID DepartmentId Name Address
1 1 Name1 address1
2 1 Name2 address2
3 1 Name3 address3
Now if you want to delete marketing department from Department table , you can delete it easily and there is no error. But now if you try to delete HR department you will get error as mentioned above because the HR department Id(i.e. 1) is already linked with another table called Employee table. So if you want to delete HR department anyhow, you must first delete all the record from employee table with DepartmentId=1 . otherwise you can use the approach as the youtuber you mentioned.
Hope it helps !

What datatype should be used to store an array in the SQL Server

I am trying to create a table in my database using Visual Studio.
I've got a table for my Products (like in online shop) and then I have a table for Orders, which should store all products that user has ordered. The problem is that I am not sure which datatype I should use when designing the database to store an array of products in my Orders table. This is what the Orders table should look like
You should create Products and Orders table with relationship between them.
Your Orders table should have Id column as well (which is PrimaryKey)
Then you should create Products table, that keeps all the information about products and additionaly OrderId which should be used as Foreign Key to Orders table.
Please look at that link:
https://msdn.microsoft.com/en-us/library/ms189049.aspx
It's also worth of checking:
One To One, One To Many, Many To Many relations in SQLServer to have better understanding and design your data store properly.
In your case you need ProductsOrders table, Many To Many relationship.
In Relational database, you can create a relationship between 2 tables.
The relationship can be
1 to 1 (1 Product - 1 Order)
1 to Many (1 Product - 'n' Order)
Many to Many (n product - 'n' Order)
Based on your scenario, You can choose any of the relationship listed above. While querying from the database, you can easily operate over each order/Product.

How do I create a table in SQL Server that stores multiple values for one cell?

Suppose I have a table for purchase orders. One customer might buy many products. I need to store all these products and their relevant prices in a single record, such as an invoice format.
If you can change the db design, Prefer to create another table called PO_products that has the PO_Id as the foreign key from the PurchaseOrder table. This would be more flexible and the right design for your requirement.
If for some reason, you are hard pressed to store in a single cell (which I re-iterate is not a good design), you can make use of XMLType and store all of the products information as XML.
Note: Besides being bad design, there is a significant performance cost of storing the data as XML.
This is a typical example of an n-n relationship between customer and products.
Lets say 1 customer can have from 0 to N products and 1 products can be bought by 0 to N customers. You want to use a junction table to store every purchase orders.
This junction table may contain the id of the purchase, the id of the customer and the id of the product.
https://en.wikipedia.org/wiki/Many-to-many_(data_model)

Database design and large tables?

Are tables with lots of columns indicative of bad design? For example say I have the following table that stores user information and user settings:
[Users table]
userId
name
address
somesetting1
...
somesetting50
As the site requires more settings the table gets larger. In my mind this table is normalized, all the settings are dependent on the userId.
I have a thing against tables with lots of columns it just seems wrong to me, but then I remembered that you can select what data to return from the table, so If the table is large I could still break it into several different objects in code. For example
[User object]
[UserSetting object]
and return only the data to fill those objects.
Is the above common practice, or are their other techniques that deal with tables with lots of columns that are more suitable to use?
I think you should use multiple tables like this:
[Users table]
userId
name
address
[Settings table]
settingId
userId
settingKey
settingValue
The tables are related by the userId column which you can use to retrieve the settings for the user you need to.
I would say that it is bad table design. If a user doesn't have an entry for 47 of those 50 settings then you will have a large number of NULL's in the table which isn't good practice and will also slow down performance (NULL's have to be handled in a special way).
Instead, have the following:
USER TABLE
Id,
FirstName
LastName
etc
SETTINGS
Id,
SettingName
USER SETTINGS
Id,
SettingId,
UserId,
SettingValue
You then have a many to many join, and eliminate NULL's
first, don't put spaces in table names! all the [braces] will be a real pain!
if you have 50 columns how meaningful will all that data be for each user? will there be lots of nulls? Most data may not even apply to any given user. Think 1 to 1 tables, where you break down the "settings" into logical groups:
Users: --main table where most values will be stored
userId
name
address
somesetting1 ---please note that I'm using "somesetting1", don't
... --- name the columns like this, use meaningful names!!
somesetting5
UserWidgets --all widget settings for the user
userId
somesetting6
....
somesetting12
UserAccounting --all accounting settings for the user
userId
somesetting13
....
somesetting23
--etc..
you only need to have a Users row for each user, and then a row in each table where that data applies to the given user. I f a user doesn't have any widget settings then no row for that user. You can LEFT join each table as necessary to get all the settings as needed. Usually you only need to work on a sub set of settings based on which part of the application that is running, which means you won't need to join in all of the tables, just the one or tow that you need at that time.
You could consider an attributes table. As long as your indexes are good, then you wouldn't have too much of a performance issue:
[AttributeDef]
AttributeDefId int (primary key)
GroupKey varchar(50)
ItemKey varchar(50)
...
[AttributeVal]
AttributeValId int (primary key)
AttributeDefId int (FK -> AttributeDef.AttributeDefId)
UserId int (probably FK to users table?)
Val varchar(255)
...
basically you're "pivoting" your table with many columns into 2 tables with less columns. You can write views and table functions around this structure to give you data for a group of related items or just a specific item, etc. You could also add other things to the attribute definition table to indicate required data elements, restrictions on the data elements, etc.
What's your thought on this type of design?
Use several tables with matching indexes to get the best SELECT speed. Use the indexes as a way to relate the information between tables using a JOIN.

Resources