From database to application scope - java

my question is involving database and application scope. I am currently running an web application that stores user info(for login), item info and purchase info. The way I am currently doing storing the data is by putting them in a List. I am thinking of storing the data to a database (mysql) and replace the lists. In thinking about it, i thought of whether it would make sense to store data in the database, but also store it in the Lists. Basically, i would be adding to the List via the database. Would it make sense to do this?Thanks!

You should not save the entire list into the field but each element in the list should be a separate row in the table. This is object-oriented design and it would be good practice to do so.
To achieve this, you need to have a one-to-many mapping for the user table to the purchase table. One user can make multiple purchases but each purchase can only be tied to one user. Therefore, your purchase table should contain a foreign key which is the ID for your user table.
For example, table A should be the list of all your users. Table B should contain all your purchases. We can see that Doug has made 3 purchases, (PA,WV and DE) while Bob has made 2 purchases (TN and NC).

Related

Save as object or just a row in database?

As a practice project, I'm creating a calorie tracking app. Part of that requires creating individual food items that can be saved for reuse. A single food item would consist of a name, a calorie count, a serving size, etc. I'm thinking about the best way to save these food items, and it seems reasonable to connect the project to a database. Specifically I'm using MySQL.
The question I have then is whether each food item should simply exist in storage as a row in a database with a column for each field (name, calories, etc), or if I should create a foodItem class with an instance for each food item. This seems redundant, but at the same time, if I don't create an object, it seems to me this would be counter to OOP principles and database use would almost always replace class/object creation. Couldn't a user just write straight into the database without creating an object? What am I missing here?
As a design practice, I like to have "software objects" such as FoodItem which, among other things, know how to "persist themselves" in an underlying database. They know how to populate themselves, and how and when to update the database. As much as possible, all of the details of "database representation" are hidden within the objects' implementations.
The actual manner in which you represent the data in the database also depends very much on your reporting requirements. Think about the sort of summary statistics, catalogs, and other things which you might need to produce from these data using separate tools.

How to create a list with data tables as items

What I want is to create a list where each item in that list is an data table like below: http://imgur.com/a/mQdi5 Example data table The user needs to be able to sort items in the data table and needs to be able to sort the data tables itself.
Each table is going to represent a client and each item in that table is an order. The user will then collect the orders, if he collected an order the order wil dissapear but the user is also able to bring them back.
I've tried to put a Recyclerview inside a Recyclerview but this caused unitended side effects and bugs, also I read online that it is basically a bad practice. My initial intention was to use a recylcerview with a sortedlist.
I did some searching online and a lot of people recommended using categories between items so that you only need one list. But because I have data tables (CardViews) that can be independent sorted this isn't an option.
If anyone want to give me a nudge in the right direction, I would be really thankful.

Many subscribers for many shops

I have many shops in Shop table and many users in User table in DB.
User can subscribe to any stores.
How can I create table for this task? First column with shop name and second column - string with comma separated user ids?
This is generally referred to as a many-to-many relationship. In a standard relational database, this is usually represented by a table with user_id and shop_id, one row for each user -> shop relationship.
You will never want to use a comma-separated string to represent multiple items in a database, as this will make queries very inefficient. For example, to find which stores user a subscribes to, you would have to parse each row of the table to find which of the comma-separated values contains a.
This is a many-to-many relationship. You need a third table, say it's called Subscription. The fields will be two foreign keys, one referencing the primary key of the User table and the other referencing the primary key of the Shop table.
You can create a table where each row represents a subscription (i.e., a pair (user,shop)).
So, you will have (at least) two columns in the table: the id of the shop and the id of the user.
Assuming that a user can subscribe to a shop only once, the pair (user_id,shop_id) should be the primary key of the table (in case you need to define a surrogate key for the table, you could add a unique constraint to the pair (user_id,shop_id)).
If you have many data and need to quickly get all the shops to which a user has subscribed, you should add an index to the user_id column.
On the other hand, if you need to quickly get all the user that subscribed to a shop, you should add an index to the shop_id column.
I believe user can subscribe to multiple shops, and one shop can have multiple users subscribed to it. In this case, it is best to use map table with shop_id from shop table and user_id from user table. ( keep the foreign key constraints) . For each subscription ,this table will keep an entry, hence no comma separated string is necessary.
It sounds like you have a classic situation in databases which marks the change between a "flat file" database and "relational database" like MySQL, Oracle or MS's SQL Server. A similar situation is Authors and Books. An author can have more than one book and some books have more than one Author.
A simple comma delimited database is a flat file and you are going to need a separate line for each relationship. For example,
ShopA, UserA
ShopB, UserA
ShopA, UserB
ShopB, UserB
In a relational database, you can isolate the user table and shop table in two separate tables and form a third table, a relations table that describes the relation and so remove redundancy in the user and shop tables,
ShopTable
ShopA, SA
ShopB, SB
UserTable
UserA, UA
UserB, UB
ShopUserRelationTable
SA, UA
SA, UB
SB, UA
SB, UB
When you want records displaying the relationship, you apply the SQL language to create a sequence of records displaying this.
This basic problem of removing redundancy in tables is what motivates the development of relational database software.
It sometimes happens that a table is complicated enough to contain "many to many" relationship like this and SQL can be further applied to analyzing and creating records reflecting these relationships. Such a table may also serve as a many to many relationship table for other tables.

Exploring user specific data in webapps

I am busy practicing on designing a simple todo list webapp whereby a user can authenticate into the app and save todo list items. The user is also only able to to view/edit the todo list items that they added.
This seems to be a general feature (authenticated user only views their own data) in most web applications (or applications in general).
To me what is important is having knowledge of the different options for accomplishing this. What I would like to achieve is a solution that can handle lots of users' data effectively. At the moment I am doing this using a Relational Database, but noSQL answers would be useful to me as well.
The following ideas came to mind:
Add a user_id column each time this "feature" is needed.
Add an association table (in the example above a user_todo_list_item table) that associates the data.
Design in such a way that you have a table per user per "feature" ... so you would have a todolist_userABC table. It's an option but I do not like it much since a thousand user's means a thousand tables?!
Add row level security to the specific "feature". I am not familiar on how this works but it seems to be a valid option. I am also not sure whether this is database vendor specific.
Of my choices I went with the user_id column on the todolist_item table. Although it can do the job, I feel that a user_id column might be problematic when reading data if the data within the table gets large enough. One could add an index I guess but I am not sure of the index's effectiveness.
What I don't like about it is that I need to have a user_id for every table where I desire this type of feature which doesn't seem correct to me? It also seems that when I implement the database layer I would have to add this to my queries for every feature (unless I use some AOP)?
I had a look around (How does Trello store data in MongoDB? (Collection per board?)), but it does not speak about the techniques regarding user_id columns or things like that. I also tried reading about this in some security frameworks (Spring Security to be specific) but it seems that it only goes into privileges/permissions on a table level and not a row level?
So the question is whether my choice was appropriate and if there are better techniques to do this?
Your choice is the natural thing to do.
The table-per-user is a non-starter (anything that modifies the database structure in response to user action is usually suspect).
Row-level security isn't really an option for webapps - it requires each user session to have a separate, persistent connection to the database, which is rarely practical. And yes, it is vendor-specific.
How you index your tables depends entirely on your usage patterns and types of queries you want to run. Is 'show all TODOs for a user' a query you want to support (seems like it would be)? Then and index on the user id is obviously needed.
Why does having a user_id column seem wrong to you? If you want to restrict access by user, you need to be able to identify which user the record belongs to. Doesn't actually mean that every table needs it - for example, if one record composes another (say, your TODOs have 'steps', each step belongs to a single TODO), only the root of the object graph needs the user id.

What's the best way to store a value from a list of pre-defined values in a database?

Let's say I have a pre-defined list of values (RW, FW, 4W) representing drive type of a vehicle:
RW - Rear Wheel
FW - Front Wheet
4W - Four Wheel
Now, I want to take a value from the above 3 values as an input from my user and then store it in a database.
Upto my knowledge, I can perform this with the help of any of the following methods:
- Hard-code the values at the UI so that the UI shows a drop-down having only the above 3 values. Then store that value in the String vehicleType field of the Vehicle vehicle object and then store it in the DB as String.
Cons:
i). No validation of the value at object level
ii). No validation of the value at DB level.
iii). Though the need for adding a new value to the list is rare, but still user can't add a new value at runtime
- Pros:
i). No need of join at DB to retrieve the vehicle object
OR
Make a separate table VEHICLE_TYPE in the DB having all the 3 values and link it with the VEHICLE table via. foreign key. And then populate the drop-down at UI from the VEHICLE_TYPE table. Store the value in the vehicle object as String
- Cons:
i). No validation at object level
ii). Need a join at DB to retrieve a vehicle object
- Pros:
i). validation of the value at DB level (by foreign key)
ii). User can add a new value to the list at runtime
OR
Make a separate table VEHICLE_TYPE in the DB having all the 3 values but DON'T link it with the VEHICLE table via. foreign key. And then populate the drop-down at UI from the VEHICLE_TYPE table. Store the value in the vehicle object and in the DB as String
- Cons:
i). No validation at object level
ii). No validation at DB level
- Pros:
i). No join required at DB level
ii). User can add new value to the list
OR
Make a separate table VEHICLE_TYPE in the DB having all the 3 values and link it with the VEHICLE table via. foreign key. And then populate the drop-down at UI from the VEHICLE_TYPE table. Make an enum VehicleType in java and then add a field VehicleType vehicleType in the Vehicle class. Store a value from the VehicleType enum in the vehicleType field based on the input of the user.
-Cons:
i). Will have to update the list at two places: VehicleType enum and the VEHICLE_TYPE table. May cause inconsistency.
ii). User can't add a new value to the list (he can add a value in the table but can't change the enum)
- Pros:
i). validation at UI level
ii). validation at object level
iii). validation at DB level
Question:
Is there other way by which we can perform the above task which doesn't have any of the above disadvantages?
Sure. Your second one with a modification:
Make a separate table VEHICLE_TYPE in the DB having all the 3 values and link it with the VEHICLE table via. foreign key. And then populate the drop-down at UI from the VEHICLE_TYPE table. Store the value in the vehicle object as String. When calling vehicle.setVehicleType(), verify that the value assigned is valid by checking the possible values from the DB. If it's invalid, throw an InvalidArgumentException or a subclass.
Now you have validation in the object. And also, I don't consider having to do a join a con. You can't do much of anything without joining tables. That's why you have many tables.
I would chose also the second approach. You have been already answered about the first con.
Regarding the second con, if performance is so important, you could use one of those approaches:
If the type vehicle is not used much in the application, lazy loading the type of the vehicle.
If you are not using database ids, because you are using the code of the type vehicle as primary key, you could add a codeType property to your vehicle class, and load this property instead of the type (which could also be loaded lazyly, depending on needs), directly from the vehicle table. Then you won't have any join.
Make a separate table Vehicle_type (Vehicle_type_id int, description varchar (you need to determine the appropraite size))to use as the lookup for the drop down menu. If you want the value to change in the main table when the look up changes (say an adimin changes seden to sedan), then store the typeid in the vehicle table. If you want this to be historical data (maybe there is no longer a type sedan but older vehicles should still be marked as sedan) then store the decription of the type in the vehicle table. In the second case you can't enforce with an FK relationship, so you will need to ensure that inserts (and updates of that value only) cannot choose values not currently in the table. The application will likely do this although you could write a trigger to do so if values are likely to change outside the application.
I don't feel that joins should be your cause for concern - you might well find that compromising the design to reduce the overhead of a JOIN is most likely going to be wasted effort. Your network latency to the db could be higher than the JOIN overhead.
How you deal with additional values entered by the user depends upon how you want them to be handled:
Treat them as true additional values. They are added to the VEHICLE_TYPE in the database, and once added, are available for all users to select.
Treat them as custom values for that particular field. I.e. the VEHICLE_TYPE includes a type "Other" and the user can enter additional details in a separate field. These are not shared with other users and do not appear in the dropdown list.
To get object-level validation, validate against the VEHICLE_TYPE. This can be done automatically with modern OIM and ORM frameworks. These allow you to define validation rules on the model which are then propagated forward to the UI for early catching of validation errors, and backwards to the database to ensure data store consistency.
You can store Vehicle ID as regular key, or the type string itself (RW,FW etc.). If using the type string itself, you don't have to join to the VEHICLE_TYPE table. You could present the string directly, or you can fetch the presentation strings from resource bundles if localization is needed.
EDIT: To see how ORM and OIM can take model validation metadata back to the db and out to the UI, see DZone: Hibernate 4 Validation, and Metawidget. With JSR 303 you can validate your objects in the UI, business layer and back end.

Categories

Resources