I'm developing a web application for the deacons in my church. And while I have a good deal of experience coding in several languages, I have yet had to do any serious database modeling until deciding to tackle this need for my organization.
I'm very familiar with writing sql/ddl queries on existing database in (strictly mysql console, Spring MVC, Boot, Java, etc.). But, not since college have I had to consider normalization, 2nf, 3nf, 1:1, 1: many, etc... It's been a humbling experience, to say the least, trying to refresh my memory with the database theories learned years before and attempting to apply the concepts.
I created a model that seems, at least to me, to fit the needs of the users
My specific question is about locked accounts. I did read several posts about it, which only confused me more about how to approach this concept with my given data model? I really would appreciate any other suggestions and/or critiques; I definitely understand the concept and power of learning by failure.... Thanks.
Use Case :
1. Users holding office in a particular year can sign into the web
application, and view their information *(Name, Account Status,
Ordained, Team number, Calendar of their assigned duty days)*.
They can only update their personal info (name, address,
phone). Note: The account will be created for users.
2. Director, Asst. Director and System admin can log into the web
application (admin dashboard) and see a data table of all users,
w/ all relevant fields(view). This group has full read-write
privileges.
I have a locked table in the model, but not sure if that is the correct way to handle updating a user's status from active to inactive. If inactive, he cannot log into the web application. I would also use this if the user attempts to log-in more the x number of times unsuccessfully. Additionally, it would be helpful (reporting and stats) to keep previous users in the database for x number of years, of course with an inactive status.
Sorry for not using diagram (I don't use diagram tools). Here's extremely basic sample with relevant bits for audit table:
CREATE TABLE users (
user_id SERIAL,
-- ...
);
-- ...
CREATE TABLE user_updates_audit (
audit_id SERIAL,
user_id INT NOT NULL,
audit_timestamp TIMESTAMP NOT NULL default now(),
-- just free form text describing applied update (maybe old value, new value, etc)
audit_text VARCHAR(1024) NOT NULL
);
ALTER TABLE user_updates_audit ADD CONSTRAINT user_updates_audit_pk PRIMARY KEY (audit_id);
ALTER TABLE user_updates_audit ADD CONSTRAINT user_updates_audit_user_id_fk FOREIGN KEY (user_id) REFERENCES users;
Sure, you may expand from here, for example, by changing free-form audit_text to some more strict scheme, e.g. foreign key to dictionary of possible update actions (ENABLED, DISABLED, whatever) and actual values being changed. Or some other more elaborate scheme more suitable for your case.
But free-form audit is some starting point.
Main value here is that you can see all modifications history of important entities in your system, not just current state.
Related
I have the following table in my db:
CREATE TABLE document (
id INT PRIMARY KEY AUTOINCREMENT,
productModelId INT NOT NULL,
comment VARCHAR(50),
CONSTRAINT FK_product_model FOREIGN KEY (productModelId) REFERENCES product_model(id),
)
Of course, real table is much more complicated, but this is enough to understand the problem.
Our users want to see the number of the document when they click button "new". So, in order to do that, we have to create object in db and send to client that object. But, there is a problem. We need to know productModelId before we save the object in db. Otherwise we will have an sql exception.
I see two possible variants (both are ugly, really):
To show modal list with product models to user and after that create object in database with productModelId chosen by user.
To create a temporary number and after that to save the object in db when user finishes editing the document and saves id. We also need to remove NOT NULL case and validate this somwhere in code.
The first way is bad because we have too much modals in our application. Our UI is too heavy with them.
The second variant is ugly because our database is not consistent without all the checks.
What can you suggest we do? Any new solutions? What do you do in your apps? May be some UI tips. We are using the first variant at the moment.
Theory says that the id you use on your database should not be a relevant information, so the user should not see it if not well hidden in an URL or similar, so you should not display it to the user, and the problem you have is one possible confirmation of this theory.
Right now the solution you have is partially correct: it satisfies technical requirements, but is still bad because if the user doesn't complete the insert you'll end up with the DB having empty records (meaning, with ID and foreign key ok, but all other fields empty or with useless default values), so you are basically circumventing the database validations.
There are two better solutions, but both require you to review your database.
The first is not to use the id as something to display to the user. Use another column, with another "id", declare it unique on the database, generate it at application, display it to the user, and then use this other "id" (if it's unique, it is effectively an id) wherever needed.
The second one is the one that is being used often cause it does not require a central database or other authority to check uniqueness of ids, so scales better in distributed environments.
Drop the use of the common "id int" auto-incremented or not, and use UUIDs. Your id will be a varchar or a binary, an UUID implementation (like java.util.UUID, but you can find in other languages) will generate a unique id by itself whenever (and wherever, even on the client for example) you need it, and then you supply this id when saving.
We make it the following way.
Created table id_requests with fields issue_type_id and lastId. We need this in order to avoid the situation when two users hit the button 'new' and get the same ids.
And of course we added field innerNum to all the tables we use this feature in.
Thank you!
I am working on a library management system in Java.
My program has two state for login:
1: User mode
2: Admin mode
In Admin mode login (in my swing GUI window) , there are a button for showing the borrowed books.
Now, I am confusing to how implement it?
Should it display that which users borrowed which books?
Or it should display that which books are borrowed?
I know that it depends on my requirements, But i want know what it should be in general?
This is my borrowed book in Mysql command-line:
Is this correct approach?
Should i display all my records in my JTable and then filter it by UserID ?
Like this?
Underlying IDs, which are database specific, in most cases, are not known to end users. They only feel comfortable referring to and working with readable and easily recognisable data in presentations.
Hence, it would be a better presentation, if you extract related book titles and user names and display them. And a search by partial user name or book name would be more appropriate for end user concerns.
And, dates should be handled using either date, datetime, or timestamp data types on column definitions. Using date functions on these type of columns would be comfortable than on varchar type data.
I think "which books are borrowed?" is better
I ll go with which books are borrowed by which user. And it should be able to sort by user so that I can see at a glance that a how many books a particular user has borrowed? Then I'll also put a limit to it as to a particular user can only borrow at the most 5 Books at a time.
I have a mySQl innodb database which has a couple of tables which store different kind of transactions of a user. In order to show a custom 'Account Statement', I have to fetch data from all of these tables every time a user wishes to see the Account Statement.
I am not sure what would be an optimized approach.
There are a lot of users (and the data keeps changing in real time) and I'm not sure if I should keep caching the sql queries.
Should I create views that combine the table and keep updating it whenever there is an update to the parent table?
Should I perform a join on these multiple tables each time a user requests for the account statement?
I was not able to find out if there is a standard design/practice for showing account statement (with pagination). Any suggestions?
Thank you.
I would recommend to start to create a JPA mapping of your tables and then using some "standard" provider (eg. Hibernate) to access your data. This will makes transparent access from Java to your data without thinking (too much) about views, etc.
Your scenario seems very common and is exactly what RDBMS are for. Do not hesitate for performance now, when going to start your first project (if it is not your first project, this question has no sense).
I am working on a web application related to Discussion forums using Java and Cassandra database.
I need to construct 'keys' for the rows storing the user's details and & another set of rows storing the content posted by the user.
One option is to get the randomly generated UUID provided by Java language, but these are 16 bytes long. and since NoSQL database involves heavy denormalization, I am concerned whether I would be wasting lots of disk space, RAM and other resources if the key could be generated in smaller sizes.
I need to generate two types of keys, one for the Users & other for Content Posted by Users.
For the Content posted by users, would timestamp+userId be a good key. where timestamp is the server time at which content was posted and userId refers to key of user row.
Any suggestions, comments appreciated ..
Thanks
Marcos
Is this a distributed application?
Then you could use a simple synchronized counter and initialize it on startup with the next available id.
On the other hand a database should be able to handle the UUID hashes as created by java.
This is a standard for creating things like sessionIds, that need to be unique.
Your problem is somewhat similar since a session in your context would represent a set of user input.
We develop and operate a blogging application in which user data a scattered across many tables:
- Blog
- Article
- Comment
- Message
- Trackback
- 50 other tables.
Users are able to close their account, and their account/contents must disappear from the site right away.
For legal/contractual reasons, we also must be able to undelete their account/content for a given duration, and also to make those data available for juridic authorities for another duration.
Over the years and different applications, we used different approaches:
"deleted" flag everywhere : Each table has a "deleted" column, which is updated when data is deleted/restored. Very nasty because it slows down every list generation queries, creates a lot of updates upon deletion/restore. Also, it does not handle the two stage deletion described above. In fact we never used this one, but it's worth dis-advising it :)
"Multi table": For each table, we create a second table with the same schema plus two extra fields (dateDeleted, reason). The extra fields are used to know if the data is still accessible for restoration, when to delete it, and why/how it was deleted in the first place. This version is just a bit better than the previous version, but can be very nasty performance wise too when tables are growing. Also, you have to change the schema of some tables (ie: remove UNIQUE constraints) which makes the system harder to understand/upgrade for new developers, administrators ... and mentally healthy people in general.
"Multi DB": Same approach as before, but we move data on a different database cluster, which allows to browse those data without impacting the "end users" db. Also, for this app, the uniqueness constraint is done at the java level, so all the schemas are the same. Lastly, the double data retention constraint is done by having a dedicated DB for each constraint, which makes things easiers.
I have to admit that none of those approaches satisfies me, even if they can work up to a certain amount of data. I have also imagined that we could just delete some key rows in the DB, and let the rest inconsistent (and scheduled for a more controlled deletion job), but it scares me ...
Do you know other ways of doing the same thing, keeping the same level of features (we could align the two durations to simplify the problem) ? I'm not looking a solution for my existing apps, but would like to improve the next ones.
Any input will be highly appreciated !
It seams that every asset (blog, comment, ...) relies on the user. I would give the user table a column "active" which is 0 or 1, Then you implement a feature to ask on each query for the different asset "user active"? Try to optimize this lookup with indizes or something like that. In my opinion its the cleanst way. After this you can implement a job, which runs a cascading delete on users disabled for longer then x days.