How to handle count of how many times some events occurs? - java

Try to get the best practice of handling count of how many times books being "i like"d. Let's say right now, I have many series of books and each series can have many books. Now, when people click "i like" to one book, I want to add 1 to the book and also add 1 to the series so that later I can render these numbers, correspondingly. Now, I am struggle on two ways.
1) when one book is clicked, I will add 1 on the "liked" column in the book table and at the same time, add 1 on the "liked" column in the series table.
2) when one book is clicked, I only add 1 on the "liked" column in the book table. When I try to do a render of the number for the series, I do a SUM on the "liked" column of the books that belong to the series.
However, both of have pro and cons. The 1) way, I can simply fetch the "liked" column of the series table when I try to show how many people liked the whole series. It will be efficient than the 2) way cause there is no aggregation needed, especially when many people try to render the series page. However, this will take more effort when we click "i like" button. Cause even when people click on different books. As long as these books belong to the same series, it will need to update the number of the series. And it will be concurrent process. On the contrary, if I don't do update on the series table when people click "i like" for the book. It will be more efficient at that level, but will waste a lot of effort to do the redundant aggregation calculation when many people try to load the same series page, where the "liked" number for the series is shown.
Any other ideas? If no, what is a better solution? 1) or 2)? Thanks in advance.

I prefer the second approach. The logic there makes more sense. Instead of just adding 1 to the series each time the book is clicked, you can just sum up the total number of likes on the series.

Store your data in Database, otherwise will lost data when server restarts.

I recommend using a database. You can have a books table and a likes table. When someone likes a book, you take the id of the book they liked and add it to the likes table.
This way you can also store the name of the person who liked it, and stop them from liking more than twice, and you can also give them the option to remove their like.
For example:
Books Table:
id, bookname, author, (and any other information)
Likes Table:
id, username, book_id, date
Then when counting how many likes there are for a single book, you can query the database and count the number of rows for where the book_id = ?

Using a RDBMS, you should focus on data integrity. The first approach can introduce an update anomaly, if not done in a single transaction. Anyway, you would have high concurrency on the series counter. So I would prefer the second approach.
Start with a denormalization only if your solution lacks of performance.

Use HttpSession
HttpSession session = request.getSession(false);
if (session == null) {
// store value in session
}
else {
// read value from session
}
Another option is to use Redux for larger Single Page Applications but only if makes sense.

Related

Which of the following SQLite database methods more efficient in storage usage and lookup speed?

I am creating an android app to store data of a card game, and I want to save each match data (Player profile IDs and player scores). I am using SQLite databases for that.
I want to sue this data to look back older matches or just load up an unfinished one.
Currently, I store each match data in a separate table, with table name of current date. I store the 4 player ids as int and 4 player scores as byte array (scores for each round).
I was thinking that I could store these data in a single table like this:
A column for match date, 4 column for player id-s as int, 4 column for player scores as byte array.
Or like this:
A column for match date, column for player ids combined as string, column for player scores combines as string.
Or like this:
A column for match date, column for player ids and scores combined as string
Typically, you would have one table which stores "the match," and a second related table which stores each one of the scores. They would not be "combined as a string."
That being said, however, it's really up to you: if your application is always going to just want the scores, all at once, and you don't intend to query against them, you could do it that way.
As you've correctly guessed, however, you do not want to have "a table per match."
Conclusion
It's going to be as complicated as you want it to be. Think about what kind of questions you want to be able to ask your database. I set out to answer a very hard question, which would have involved another significant change to the proposed schema or a much more complicated query involving sub-queries, or maybe just SQL functions that I'm not very familiar with. I needed to do more research.
I can usually figure this stuff out if I have too, but I'm not a database expert, so it's far from simple for me. I thought I was pretty good with databases until I got into the nitty gritty on this one lol.
Hope I didn't confuse you too much. I seriously thought about erasing my answer, but I put all this time into it. I gave you a bad answer. But I hope it's helpful anyway.
Woah
So, I set out to help & answer your question, then I started having fun with it, then I realized I was in over my head. So please take my lengthy answer lightly & don't overcompmlicate it for your current knowledge & skill level.
As far as databasing goes, what you're trying to do is pretty simple, but I understand how overwhelming & difficult databases can be before you get the hang of them.. Keep reading & you'll see why I struck this. If you stuck to the final scores, then it wouldn't be too complicated. If you want to re-load a game where it left off, it might get pretty complex.
In code, there are so many ways you can do the same thing, and there's rarely one "right" answer. Anyway, I'll comment on the approaches you've suggested.
the problem
You have a card game, which you're representing in a database as a match_date, player_profile_id, and player_score. There are four players per game. And you want to look at or load up old matches to continue them.
Options you gave
I store each match data in a separate table, with table name of current date. I store the 4 player ids as int and 4 player scores as byte array (scores for each round).
Having a separate table for each game is... clunky, to say the least.
I was thinking that I could store these data in a single table like this: A column for match date, 4 column for player id-s as int, 4 column for player scores as byte array.
Good. Switching to a single table is a huge improvement, but the data is still compacted in formats that are not query-able, and having different columns for each player is not necessarily ideal, but it would serve the task at hand.
A column for match date, column for player ids combined as string, column for player scores combines as string.
I like that you're trying to condense the table and not have things so wide. But condensing the data in this way pretty much defeats the purpose of a database. You wouldn't be able to query for specific information, and you'd probably lose performance because your Android code (Kotlin, right?) would have to unpack the data. However I don't have benchmarks to prove that.
A column for match date, column for player ids and scores combined as string
This, as with the previous one, again tightly couples your database to your Android code. The database should be doing the data-base job & the Android code should be doing the Android job. What I mean is that your database should be portable without complicated logic to extract the information you need. The query should extract the information you need.
My suggestion
It's good that you're considering different ways to do things, and it sounds like you have a solution that is currently doing the job. What you will likely have, though, is growing pains. I'm gonna add a whole lot of database stuff now that you don't need to implement at this time. Sometimes it's better to do what you have the skills for now so that you can get the current task done. Sometimes it's better to do the complicated thing you don't know how to do so you can learn. That depends on your situation.
So. We're going to have round and player and match.
The schema
round table:
id | match_id | player_id | round_number | hand /*at the start of the round*/
87 | 3 | 96 | 0 | ["ace of spades", "kind of hearts", "7 of clubs"]
99 | 3 | 85 | 3 | [...]
and so on
Then your player table would have columns for name, id, etc. Your match table would contain the date of the match, a match id, and any other match data
Critiques of my solution
If you want to query like "How many times were games on round 7 while a player had an ace in their hand and no kings were left in the deck", then you'll need to unpack hand into it's own table as well.
I personally prefer camelCase column names over under_score names. But I think under_score is more commonly used for databases. I have nothing to back that up.
UUIDs are a thing. I haven't personally started using them and it doesn't seem necessary for your use case.
Let's get confused
I want to answer the question: "How many times were games on round 7 while any player had an ace of hearts in their hand, no player had a 2 of clubs, and no kings were left in the deck?"
deck_start table has the columns: matchId, cardName, cardFace, 'index'
match table has the columns: id, name, date, type (if there are different types of matches)
card_in_hand table has the columns: id, matchId, playerId, roundNumber, cardName, cardFace
So to answer the question
How many times were games on round 7 while any player had an ace of hearts in their hand? no player had a 2 of clubs, and no kings were left in the deck?
SELECT COUNT(DISTINCT match.id) FROM match
JOIN card_in_hand ON match.id = card_in_hand.matchId
WHERE card_in_hand.roundNumber = 7
AND card_in_hand.cardName LIKE 'ace'
AND card_in_hand.cardFace LIKE 'heart'
Or something like that. I struck the second part of the question... The more I thought about it, the more complicated it got. You'd have to either keep track of the full deck on each round, or use count of distinct cards in hand to figure out your deck index. Or maybe an approach where you keep track of the starting deck, then keep track of every single play. That's probably the one, really. If you track every single play.
play table might contain id, matchId, playerId, roundNumber, sequenceNumber, action
And then you might have an action table or otherwise further expand action.
You also might want to keep the id column in the match table as matchId and not just id. If you start doing joins & you want to get the correct id (match v round v play v whatever), then you'd be better off having it as table.tableId instead of table.id
I'll try to actually answer your question with this one.
I was thinking that I could store these data in a single table like this: A column for match date, 4 column for player id-s as int, 4 column for player scores as byte array.
I think this is the closest one. But I think it could be expanded a little. I don't actually know what data you're working with so I have no idea how player_scores should be represented, but I'll roll with a byte array.
match table: matchId (int), matchDate (timestamp or date type) (and any other columns for metadata like a nickname for the match, a type if there are different types of matches etc )
score table: matchId, scoreId, playerId, playerPosition, score
And here, score is the byte array.
Then to query:
SELECT score.* FROM score
JOIN match ON score.matchId = match.matchId
WHERE match.matchDate > /* start_date_for search */
AND match.matchDate < /* end_date_for_search */
Then you would get back four rows per match if you had four players in a match & you could loop over those for rows for the player-specific data.

Select primary key for two value

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.

Table relationships Many to many without a middle table in sql?

I am making an app that can lookup creatures and am in the process atempting to increase my knowledge.
I have a table Creatures and a table Skills
A creature and have multiple skills and a skill can be used by multiple creatures.
I am coding in java using sql manager.
I am using 1,2 to represent skills in the creature table and reference the skills table using the numerical values.
One thought I had was is there a way to make an overloaded stored procedure?
I have not started coding yet as I am still planning but would appreciate any ideas sent my way.
I am not trying to avoid the middle table just see if there is a way to do it another way that is not so hard its pointless.
You will probably need the middle table.
Storing a comma-separated list of skills in the Creatures table makes it easy to fetch the skills per creature, but what if you ever want to know the creatures who have a given skill?
Comma-separated lists are fraught with problems. You can use them to optimize one way of accessing the data, but that causes a drastic de-optimization of other ways of accessing the data.
See also my answer to Is storing a delimited list in a database column really that bad?
If you're using a relational database, the "right" and general way to solve it is with a table that will store the relation.
If you want to avoid the middle table, you can put a constraint on the maximum number of skills per creature - let's say max 5 skills, and then have fields called skill1, skill2, ..., skill5. I cannot recommend this option, because it will make querying much more complicated, but for some cases it's possible.
Another improvement of this option, would be a single int or long field, where each bit represents a skill. Still not good in my opinion though.

How to Iterate across records in a MySql Database using Java

I have a customer with a very small set of data and records that I'd normally just serialize to a data file and be done but they want to run extra reports and have expandability down the road to do things their own way. The MySQL database came up and so I'm adapting their Java POS (point of sale) system to work with it.
I've done this before and here was my approach in a nutshell for one of the tables, say Customers:
I setup a loop to store the primary key into an arraylist then setup a form to go from one record to the next running SQL queries based on the PK. The query would pull down the fname, lname, address, etc. and fill in the fields on the screen.
I thought it might be a little clunky running a SQL query each time they click Next. So I'm looking for another approach to this problem. Any help is appreciated! I don't need exact code or anything, just some concepts will do fine
Thanks!
I would say the solution you suggest yourself is not very good not only because you run SQL query every time a button is pressed, but also because you are iterating over primary keys, which probably are not sorted in any meaningful order...
What you want is to retrieve a certain number of records which are sorted sensibly (by first/last name or something) and keep them as a kind of cache in your ArrayList or something similar... This can be done quite easily with SQL. When the user starts iterating over the results by pressing "Next", you can in the background start loading more records.
The key to keep usability is to load some records before the user actually request them to keep latency small, but keeping in mind that you also don't want to load the whole database at once....
Take a look at indexing your database. http://www.informit.com/articles/article.aspx?p=377652
Use JPA with the built in Hibernate provider. If you are not familiar with one or both, then download NetBeans - it includes a very easy to follow tutorial you can use to get up to speed. Managing lists of objects is trivial with the new JPA and you won't find yourself reinventing the wheel.
the key concept here is pagination.
Let's say you set your page size to 10. This means you select 10 records from the database, in a certain order, so your query should have an order by clause and a limit clause at the end. You use this resultset to display the form while the users navigates with Previous/Next buttons.
When the user navigates out of the page then you fetch an other page.
https://www.google.com/search?q=java+sql+pagination

How DB Index Works?

I am trying to find out find out How DB index woks and when it should be used. I read some articles on that and one important one i found is at How does database indexing work?.
How it works:-
Advantage2:- After reading the discussion at above link , the one thing index helps is it reduces the number of data blocks to iterate through as explained in example1.
Advantage1:- But again one question came to my mind , after introducing the index also it has to search the index from index table(which any data store makes internally) which should be time again. So after further reading i found out that index are stored in efficient way usually using data structure like B trees thru which can drill down to to any value quickly and after going to node it will give us the exact memory location of record for that value given in where or join condition.Correct? So basically index srores the value of record on which we are creating index and memory location of actual record.
When it should be used:- AS we know if we create index on any column and if we insert/update/delete any value for that column , index needs to be updated for that column in index table. So it will take bit extra time and memory during CUD operation. So when it should be used .Imagine we create a customer one at a time from User screen.So total customer at end of day are 1 million. Now if we want to search customer for whose belongs to NewYork.here index will help a lot. Agreed it will slow down the insert customer a bit, it will be fractionally bad, but performance we will get during retrieval for new york customer will be exceptionally good.
Please correct me if you agree/disagree with above finding?
Your general conclusions are pretty much ok.
Yes, for some queries, an index means less data blocks need to be read.
Yes, the default index type in Oracle is implemented internally using a B-Tree.
Yes, there is some overhead for Create/Update/Delete operations on a table with indexes - both in terms of performance and space used - but this overhead is usually negligible, and easily justified when the improvement to the performance of queries is considered.
I heartily recommend reading the Oracle Concepts Guide on indexes.
Previous responds (and your conclusions) are correct. With regard to when to use indexes, it might be easier to discuss when not to use indexes. Here are a couple of scenarios in which it might not be appropriate to use an index.
A table in which you do a high-rate of inserts, but never or rarely select from it. An example of such a table might be some type of logging table.
A very small table whose rows all fit into one or a couple of blocks.
Indexes speed up selects.
They do this by reducing the number of rows to check.
Example
I have a table with 1,000,000,000 rows.
id is a primary key.
gender can be either male or female
city can be one of 50 options.
street can be lots of different options.
When I'm looking for a unique value, using an index it will take 30 lookups on a fully balanced tree.
Without the index it will take 500,000,000 lookups on average.
However putting an index on gender is pointless, because it will not reduce the search time enough to justify the extra time needed to use the index, lookup the items and than get the data in the rows.
For city it is a border case. If I have 50 different cities a index is useful, if you have only 5 the index has low cardinality and will not get used.
Indexes slow down inserts and updates.
More stuff to consider
MySQL can only use one index per (sub) select per table.
If you want to use an index on:
SELECT * FROM table1 WHERE city = 'New York' AND Street = 'Hoboken'
You will have to declare a compound index:
ALTER TABLE table1 ADD INDEX index_name (city, street)

Categories