Correct relations to Loans table? - sql

Hello stackers!
Ive made a library databse, i was wondering.. i am making one-to-one relation between Copies and Loans. and one-to-many relation from Users to Loans.
Since a copy of a book only should be allowed to be assigned one loan at a time, and a loan should only be able to containt one copy of a book. if they rent other books, its multiple loans.
and a user should be able to make multiple loans, but a loan can only be assigned one specific user.
is my current relations between these three tables correct?
if not, i would love to know how to fix it, and the reason to my failed logic on the issue.
thank you in advance!

Following on from the earlier answer. If you add a User_Roles table it could/(will) prevent you from falling into the membership trap. If you assume a user with the Admin role can perform every function a user with only Basic role, then every function which requires role-checking has to have a list of acceptable roles (Admin + Basic). Many times it is more efficient to just directly assign all the different roles, i.e. Basic AND Admin, to individual users. Then when a feature requires Basic role-authorization all users can treated the same way. It's simpler in the long run.
The Loans table has a number of issues. First, there's no primary key, to be consistent with the rest of your design, it could be a LoanID. CopyID should a foreign key to the Copies table (maybe that's what is currently drawn).
One 'advanced' or modern approach to your data model could be to use a temporal table to model the Copies. Since a single copy may only be lent out 1 time, properties of the loan could be add to the Copies table. Then anytime a change is made the System Version'ed Copies table the Copies_history table would automatically keep a full accounting of all prior loan activity.

The model looks good to me. You may need to apply some in the logic to enforce a user to have only one loan with same copy of a book.
A user will be able loan a copy over and over again ? then the relationship to loan to copy 1:M

Related

Should I use many to many relationship?

I am working on a university project for a library and I have a table USERS with a column
ROLES ( possible values: member, librarian, admin).
I've always heard that I shouldn't use many to many relationships. The reason such a relationship exists here is because a LOAN has user_id for the borrower and Id for the Librarian that was working at the time. (Table LOAN connects to table BOOK with other relationships as authors and genre etc. not needed for this question)
QUESTION
I don't see a way or a point to split this relationship in a many-to-one and one-to-many. Is what I am doing wrong for some reason?
Edit*: Forgot to add FK in my diagram for Librarian_borrowed, Librarian_returned, but they are FK's. Also a librarian can also borrow a book.
Thank you for your time.
P.S. I've thought about splitting the table USERS or using generalization, but I don't see any real benefits and I quite like it this way, keeps things easier for my project. This is not my question but I'm sure someone might comment on it.
No need for m2m relationships. You need to add multiple FKs to LOAN table, one for each relationship to the USER table e.g. borrower_id, librarian_id, etc.
They will each reference a different user record (unless, of course the librarian also borrows a book)

SQL - MS Access Form design - add data of ISA relationships

I'm taking a DBMS course and I need to design and build my own DB. I have a database for a hospital where doctors,nurses,support staff etc are in a ISA relationship to an Employee entity with the rest of the data like the name, address , salary and the rest of the employee data.
Designing a form, I want to be able to add an employee with all of their data in one form.
Is there a way to do a "conditional table" of sorts where if i select "doctor" from a drop-down i get to add to the doctor table too, and same for the rest of the entities under the ISA relationship?
Thx!
As a general rule, when dealing with data, you do NOT flip or switch tables for a given form or relatonal database design.
So, for example. If I have a table of customers. Well, now if I want to mark some of the customers as plumbers, and others as doctors? I don't create two tables.
All I would do is add ONE column to that customers table and it would simply allow me to set the type of customer. The reason for this design is "many" but some significant reasons are:
For each new type of customer, you would not create a new table. Worse, all of the forms, the reports, the SQL, the code you write? Well, all of that code would have to be modified EACH time you create a new table. So, you SIMPLY cannot adopt a design in which the concept of changing a table is part of that process.
Forms are bound to ONE table. For related data, you in most cases will use a sub form.
So, think of even a accounting system. They can have huge numbers of customers, and as a result, you can "query" that table to give you all customers. Or you might ask how many accounting firms are in the customer list. Or make a report that summeries by customer type a "count" of each type of customer.
So, buidling forms, or reports? They cannot on the fly "change" the tables they are using.
So, in place of a tables called:
SalesJan
SalesFeb
SalesMar
etc.
Well, now you can't query sales from Jan to mar, because the data is in different tables.
So, what you do is have ONE table called "sales", and you add ONE column of the date. Now, at the start of each new month, you don't have to create a new table.
Now, of course in some cases it makes sense to create a separate table. For example, a table of customers, and a table of employees in a database is just fine. It makes sense in this case to use two tables, since the information about a customer and what they can do and the kind of information is VERY different then how you would deal with employees.
So, with above? Well, if I need to print mailing labels for all customers and all employees? That would require two different reports. And very likely the table structure for the two tables is different.
Bottom line:
If you working on design or form or report? And you needing to try and change the table that the form/report/code etc is going to operate on? This is a sign that your design approach has gone complete off the rails and is the wrong design.
So, in the case of doctors, nurses etc.? Well, they are all hospital staff, and MOST of the basic information about such employees will be common, much the same, and thus a SINGLE table of "employees" makes the most sense. You would only need a nice "employee type" combo box on that one form, and thus you can add/enter/edit/search any employee in that one table.
The fact that you "want to search" for a employee show that all these people "are" employees and thus belong in one table. And the basic information about all employees is going to be the same anyway. If you find you are attempting to create a new table but with near identical structures over and over, then just like a new table for each month sales, or a new table for each new kind of employee? Simply add the "one" column that allows you to make that distinguish, and not a whole new table.
Now one COULD even attempt to put patients in the same table, but then again, dealing with patents as opposed employees is a considerable different kind of "thing".
So employees are employees - even different kinds. (manager, cleaning staff etc.).
And patients are patients - even different kinds (long term care, emergency etc.).

Opinions on planning and avoiding data redundancy

I am currently going to be designing an app in vb.net to work with an access back-end database. I have been trying to think of ways to reduce down data redundancy
and I have an example scenario below:
Lets imagine, for an example purpose, I have a customers table and need to highlight all customers in WI and send them a letter. The customers table would
contain all the customers and properties associated with customers (Name, Address, Etc) so we would query for where the state is "WI" in the table. Then we would
take the results of that data, and append it into a table with a "completion" indicator (So from 'CUSTOMERS' to say 'WI_LETTERS' table).
Lets assume some processing needs to be done so when its completed, mark a field in that table as 'complete', then allow the letters to be printed with
a mail merge. (SELECT FROM 'WI_LETTERS' WHERE INDICATOR = COMPLETE).
That item is now completed and done. But lets say, that every odd year (2013) we also send a notice to everyone in the table with a state of "WI". We now query the
customers table when the year is odd and the customer's state is "WI". Then append that data into a table called 'notices' with a completion indicator
and it is marked complete.
This seems to keep the data "task-based" as the data is based solely around the task at hand. However, isn't this considered redundant data? This setup means there
can be one transaction type to many accounts (even multiple times to the same account year after year), but shouldn't it be one account to many transactions?
How is the design of this made better?
You certainly don't want to start creating new tables for each individual task you perform. You may want to create several different tables for different types of tasks if the information you need to track (and hence the columns in those tables) will be quite different between the different types of tasks, but those tables should be used for all tasks of that particular type. You can maintain a field in those tables to identify the individual task to which each record applies (e.g., [campaign_id] for Marketing campaign mailouts, or [mail_batch_id], or similar).
You definitely don't want to start creating new tables like [WI_letters] that are segregated by State (or any client attribute). You already have the customers' State in the [Customers] table so the only customer-related attribute you need in your [Letters] table is the [CustomerID]. If you frequently want to see a list of Letters for Customers in Wisconsin then you can always create a saved Query (often called a View in other database systems) named [WI_Letters] that looks like
SELECT * FROM Letters INNER JOIN Customers ON Customers.CustomerID=Letters.CustomerID
WHERE Customers.State="WI"

Database design for CRM User table for a specific scenario

I'm designing a database for our CRM system and need some help with the CRM User table.
Types of users:
Admin
Sales Reps from Branch 2
Sales Reps from Branch 3
Client login
Now for this scenario would it make sense to have all users in a single table and have a table attribute called "type" to identify the type of user? OR should I have a seperate table for each type of user? Also, there will be some information sharing between the Sales reps.
Typically, I usually go with one User table with a Type associated with it. If you have additional Sales Rep attributes you want to store, create a SalesRep table with a foreign key back to the User table. Then, create a view that joins User and SalesRep, so it looks, logically, like there's just a usvSalesRep table that has all of the attributes you need for Sales Reps.
But, this depends a lot on data volume and transaction load, so additional information you can supply there is useful.
It depends on the number of users that you expect.
But usually a single table is enought.
If you'll have billions of users maybe you can do horizontal partitioning and make multiple tables.
Single table should be fine. And I disagree that the number users really have much impact on its design in this case.
Whenever possible, you should design your tables to mimick real life. Admin, Sales Rep, etc are just descriptions/attributes of who they are. Ultimately, they are all "People"... or User. So having one "User" table with "Admin", "SalesRep" as attibutes makes sense to me. Use the "Type" approach only if the user can only be one "Type". Use separate columns if they can be multiple user types. Ie. one can be a SalesRepBranch2 and SalesRepBranch3 at the same time. Might consider normalizing this even further.

Adding new fields vs creating separate table

I am working on a project where there are several types of users (students and teachers). Currently to store the user's information, two tables are used. The users table stores the information that all users have in common. The teachers table stores information that only teachers have with a foreign key relating it to the users table.
users table
id
name
email
34 other fields
teachers table
id
user_id
subject
17 other fields
In the rest of the database, there are no references to teachers.id. All other tables who need to relate to a user use users.id. Since a user will only have one corresponding entry in the teachers table, should I just move the fields from the teachers table into the users table and leave them blank for users who aren't teachers?
e.g.
users
id
name
email
subject
51 other fields
Is this too many fields for one table? Will this impede performance?
I think this design is fine, assuming that most of the time you only need the user data, and that you know when you need to show the teacher-specific fields.
In addition, you get only teachers just by doing a JOIN, which might come in handy.
Tomorrow you might have another kind of user who is not a teacher, and you'll be glad of the separation.
Edited to add: yes, this is an inheritance pattern, but since he didn't say what language he was using I didn't want to muddy the waters...
In the rest of the database, there are no references to teachers.id. All other tables who need to relate to a user
use users.id.
I would expect relating to the teacher_id for classes/sections...
Since a user will only have one corresponding entry in the teachers table, should I just move the fields from the teachers table into the users table and leave them blank for users who aren't teachers?
Are you modelling a system for a high school, or post-secondary? Reason I ask is because in post-secondary, a user can be both a teacher and a student... in numerous subjects.
I would think it fine provided neither you or anyone else succumbs to the temptation to reuse 'empty' columns for other purposes.
By this I mean, there will in your new table be columns that are only populated for teachers. Someone may decide that there is another value they need to store for non-teachers, and use one of the teacher's columns to hold it, because after all it'll never be needed for this non-teacher, and that way we don't need to change the table, and pretty soon your code fills up with things testing row types to find what each column holds.
I've seen this done on several systems (for instance, when loaning a library book, if the loan is a long loan the due date holds the date the book is expected back. but if it's a short loan the due date holds the time it's expected back, and woe betide anyone who doesn't somehow know that).
It's not too many fields for one table (although without any details it does seem kind of suspicious). And worrying about performance at this stage is premature.
You're probably dealing with very few rows and a very small amount of data. You concerns should be 1) getting the job done 2) designing it correctly 3) performance, in that order.
It's really not that big of a deal (at this stage/scale).
I would not stuff all fields in one table. Student to teacher ratio is high, so for 100 teachers there may be 10000 students with NULLs in those 17 fields.
Usually, a model would look close to this:
I your case, there are no specific fields for students, so you can omit the Student table, so the model would look like this
Note that for inheritance modeling, the Teacher table has UserID, same as the User table; contrast that to your example which has an Id for the Teacher table and then a separate user_id.
it won't really hurt the performance, but the other programmers might hurt you if you won't redisign it :) (55 fielded tables ??)