flexible table in SQL [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have a form php page that sends information about jobs. Each user can register unlimited jobs, so I need a flexible table in my database that when user insert new job, the table will get the values and save the information as job 1,job 2 ... job n.
Is there a way or maybe a simpler way?

Just to expand on my comment:
Your best bet here is a table for users:
user_id | name | other | attributes | for | a | user | like | birthdate
And a seperate table for the user's relationship to a job
user_id | job_id
If you need to store information about a job, then do it in yet another table
job_id | job_name | other | attributes | for | a | job
Now your database schema doesn't have to change dynamically as new data comes in. The only thing that grows is your record count. This is proper database design. You can query for all the job names associated to a user:
SELECT user.name, job.job_name
FROM user
INNER JOIN user_job ON user.user_id = user_job.user_id
INNER JOIN job ON user_job.job_id = job.job_id
WHERE user.user_id = 123
The direction you were heading where your schema changes as new data comes in will cause you nightmare scenarios down the line and should be avoided at all costs. For instance, imagine the same query where the number of job columns grows as new data comes in:
SELECT user.name, user.job1, user.job2, user.job3... how do I know where to stop for this user?
FROM user
WHERE user_id = 123

Related

Querying multiple Data Sources together [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
We have multiple data sources, which have more than a billion records in different tables, most of them are Oracle SQL data sources along with a few NoSQL solutions. The primary fields have different names in different sources. SQL Queries can only join tables in a particular data source. Writing REST API's and stitching data in each API is not possible as our queries are dynamic and might change over time.
How can we tackle this problem, Can GraphQL servers help us stitch multiple data sources and query each with different conditions?
What we seek is a query language that can query across data sources, stitch them together based on certain conditions like join queries and return us the resultset.
Table 1(Oracle SQL server 1):-
|username | age | tenant |
abc 56 US
xyz 32 IN
Table 2 (Oracle SQL server 2):-
|userid | config | duration |
abc {..json.} 2100s
the query could be like:-
select * from table1, table2 where table1.userid=table2.username and duration>2000s
CREATE DATABASE LINK dblink1
CONNECT TO user1 IDENTIFIED BY password1 USING 'connect1';
CREATE DATABASE LINK dblink2
CONNECT TO user2 IDENTIFIED BY password2 USING 'connect2';
select * from table1#dblink1 AS t1, table2#dblink2 AS t2 where t1.userid=t2.userid and t2.duration > 2000;
Note: DB Link should be created once, select could be repeated many times.
CREATE DATABASE LINK has many options, but I hope the idea helps.

SQL database design for bookmarking an item [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I have a web application in which each user is allowed to add its own items.
These items are not public or shared/visible accross the users. In other words, if user 1 creates an item, that item is only belongs to user 1.
[table: item]
id title content
1 ... ...
2 ... ...
3 ... ...
[table: bookmark]
item_id user_id
1 1
2 1
3 2
I need a "bookmarks" page which shows those items that the user has bookmarked. Does it make sense to use a separate table bookmark like I did above?
If you use create a new column named bookmark and bookmark_reference of the type uniqueidentifier for both tables, and your code simply puts a GUID (or the SQL function NEWID()) when a user does a bookmark.
Your bookmark table replace item_id with bookmark_reference and another varchar(100) column table_reference.
Thus making your bookmarking functionality generic for the whole system, any table, can be used for bookmarking or any other text the user would want to record against this particular record of this particular table.
Like custom 'notes' against a customer for just this user.
To make a "public" bookmark/note, just use either a zero or a null in user_id.
Just giving you basic ideas. The ERP Syteline from INFOR uses this type of functionality, but they use a guid (uniqueidentifer) for the user_id equivalent field, making the table unreadable without a INNER JOIN to the users table. So using user_id will make everyone's life easier down the road.
So the structure would be like this:
[table: item]
id title content bookmark
1 ... ... {guid abc}
2 ... ...
3 ... ...
[table: bookmark]
bookmark_reference table_reference user_id
{guid abc} item 1
{guid def} item 1
{guid xyz} customer 2
{guid 123} user 1
Fun fact with this structure, a user could have a bookmark on a user!
Edit: Link to a StackOverflow article on using uniqueidentifier

Does it follow best-practice DB design to mix staff and customer details in 1 table?

I have a table called Users which is currently holding data on both Customers and Staff. It has their names and emails and passwords etc. It also has a field called TypeOfUserID which holds a value to say what type of user they are .e.g Customer or Staff
Would it be better to have two separate tables: Customers and Staff?
It seems like duplication because the fields are the same for both types of user. The only field I can get rid of is the TypeOfUserID column.
However, having them both in one table called Users means that in my front-end application I have to keep adding a clause to check what type of user they are. If for any reason I need to allow a different type of user access e.g. External Supplier then I have to manage the addition of TypeOfUserID in multiple places in the WHERE clauses.
Short Answer:
It depends. If your current needs are met, and you don't foresee this model needing to be changed for a long time / it would be easy to change if you had to, stick with it.
Longer answer:
If staff members are just a special case of user, I don't see any reason you'd want to change anything about the database structure. Yes, for staff-specific stuff you'd need to be sure the person was staff, but I don't really see any way around that- you always have to know they're staff, first.
If, however, you want finer-grained permissions than binary (a person can belong to the 'staff' group but that doesn't necessarily say whether or not they're in the users' group, for instance), you might want to change the database.
The easiest way to do that, of course, would be to have a unique ID associated with each user, and use that key to look up their group permissions in a different table.
Something like:
uid | group
------------
1 | users
1 | staff
2 | users
3 | staff
4 | users
5 | admin
Although you may or may not want an actual string for each group; most likely you'd want another level of indirection by having a 'groups' table. So, that table above would be a
'group_membership' table, and it could look more like:
uid | gid
------------
1 | 1
1 | 2
2 | 1
3 | 2
4 | 1
5 | 3
To go along with it, you'd have the 'groups' table, which would be:
gid | group
-------------
1 | users
2 | staff
3 | admin
But, again, that's only if you're imagining a larger number of roles and you want more flexibility. If you only ever plan on having 'users' and 'staff' and staff are just highly privileged users, all of that extra stuff would be a waste of your time.
However, if you want really fine grained permissions, with maximum flexibility, you can use the above to make them happen via a 'permissions' table:
gid | can_create_user | can_fire_people | can_ban_user
-------------------------------------------------------
1 | false | false | false
2 | true | false | true
3 | true | true | true
Some Example Code
Here's a working PostgreSQL example of getting permissions can_create_user and can_fire_people for a user with uid 1:
SELECT bool_or(can_create_user) AS can_create_user,
bool_or(can_fire_people) AS can_fire_people
FROM permissions
WHERE gid IN (SELECT gid FROM group_membership WHERE uid = 1);
Which would return:
can_create_user | can_fire_people
----------------------------------
true | false
because user 1 is in groups 1 and 2, and group 2 has the can_create_user permission, but
neither group has the can_fire_people permission.
((I know you're using SQL Server, but I only have access to a PostgreSQL server at the moment. Sorry about that. The difference should be minor, though.)
Notes
You'll want to make sure that uid and gid are primary keys in the users and groups table, and that there are foreign key constraints for those values in every other table which uses them; you don't want nonexistent groups to have permissions, or nonexistent users to be accidentally added to groups.
Alternatively
A graph database solves this problem pretty elegantly; you'd simply create edges linking users to groups, and edges linking groups to permissions. If you want to work with a technology that's currently sexy / buzzword compliant, might want to give that a try, depending on how enormous of a change that'd be.
Further information
The phrase you'll want to google is "access control". You'll probably want to implement access control lists (as outlined above) or something similar. Since this is primarily a security-related topic, you might also want to ask this question on sec.se, or at least look around there for related answers.
Even they look similar, they are logically from different areas. You will never need a union between those tables. But as your application develops, you will need to add more and more specific fields for these tables and they will became more different than similar.
You could have a seperate table for staff holding only id from the user table as the foreign key. If you do that, then any functionality related only to the staff member can query the staff table joining to the user table. This solution will also give you the fexibility for the future extension as any data releted only to the staff (for example department they work) member can be placed in the staff table.

Search with result priority based on different condtions [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
I have a auto-complete search box that I am working on for a client. The database is in SQL Server and there is a big set of data.
I've been able to do a standard LIKE query to the database which is not that much of a problem, but the client has come up with some requirements.
Let's say the search keyword is "London Airport"
The results that show up must have certain precedence. Here are the precedence criteria:
The results with London and Airport as match must show at the top. e.g. London Airport, London Main Airport etc.
The results with London must follow, since it matches the city field.
Airport would then follow, as it is the catagory part.
The requirement is actually to include UK results first but I have already taken care of that.
Let's say the table is
Airport_name | country | city | geo_id and so on.
I've created a table function that splits the keyword into table rows of results and then I've done the like query
LIKE '% split_table.result %'
the trouble is even for the 1st criteria, the above approach is doing an OR query, showing results with London and Airport only... I want to do an AND query here and would appreciate it if I could use the split table function I've created.
I need some idea about how to set these priorities.
I'd really appropriate some help.
One plan of action is to build the separate result sets and union them together
select Id, Name
from
(
Select Id, Name, 1 as SearchRank from tables where (primary filter)
union
Select Id, Name, 2 as SearchRank from tables where (secondary filter)
union
Select Id, Name, 3 as SearchRank from tables where (tertiary filter)
) results
group by Id, Name
order by Min(SearchRank)
Hope this helps as you are using sql server
http://technet.microsoft.com/en-us/library/ms142559%28v=sql.105%29.aspx

Commonly concepts in adding contacts for staffs using master table [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Using MS SQL: The scenario is I have already a Contact master table (tbl_Customer)for all contacts in the company. The staffs suggested that they do not want to see all the contact and that they will only choose which contacts are applicable for them. The contact table is not gonna be store on the client like an outlook's pst file but on server side particularly on the database.
The methods i can use are:
1.) every time i add a staff i create a new independent table for the staff and the staff just adds the contact he/she needs from the master table via a program.
2.) I can change the contact master table to add say 50 fields with names staff01, staff02 and so on... I will make use of this fields as a marker that this rows of customer is a contact of the staff on the fields.
3.) I do a completely new contact list. Adds a field name "User". Mark the initial records via putting "ALL" on the field name. If a staff adds a contact, the table add a record with his/her name on the field "User". There will be an Auto numbered field as primary index.
Currently I'm tempted to use 3.) are there any other better method for my problem?
Why don't you have a staff table with a staff id - then every contact the staff in question wants can be a row in staffContacts. Column 1 is staffID and col 2 is contactID. Then you can join on the contact table to retrieve the details you want.
The contacts table then only needs be updated...You only need to add one table with two columns. You may wish to impose constraints that let fields be entered that are unique to staffID and contact ID and are valid staff members and contacts.
Nick.
If I understand correctly you want to have a list of the contacts that is filtered specifically based on a particular users preferences?
Personally I would create another table like this:
Create Table UserContactPreferences
(
ID int identity(1,1),
UserID int,
ContactID int,
)
And then each individual user can pick what contacts they want visible and you can add an entry here for it.
Then when you query the database you can do something like this, passing in the CurrentUser in the query:
SELECT c.*
FROM tbl_Customer c
JOIN UserContactPreferences up on c.contactID = up.contactID
WHERE up.UserID = #CurrentUser
This will then only return Customers that the user has specifically said they want to see.
In case many staff members have the same relevant contact - you should use a connection table, in which there will be 2 columns - one with the contact id , and one with the staff member id, use this table to query for staff's relevant contacts.
In case each contact has only one staff, than simply add a column with the relevant staff id, which will be a foreign key to the staff's table.
In any case and for other users to learn from:
method 1 you suggested is a big no no in SQL DB design, you need a really good reason for a DB with dynamically created tables.
method 2 is bad practice since most of the space will be wasted (unless defined as sparse columns but even though.. still space consuming) and also too specific - what will happen when you add a new staff member ? add a new column ? lock the whole DB for it and add many wasted space allocated?