Database design for webpage tracker - java

I want to design a page tracker database table, but I am facing few issues with it.
create table pageTracker(
ID bigint(20) NOT NULL,
TrackerID bigint(20) NOT NULL,
SessionID varchar(100) NOT NULL,
pageViews bigint,
pageVisits bigint,
primary key(ID)
);
If I update pageviews and pageVisits corresponding to specific SessionID I can not query pageViews and pageVisits within specific time interval.
create table pageTracker(
ID bigint(20) NOT NULL,
TrackerID bigint(20) NOT NULL,
SessionID varchar(100) NOT NULL,
pageViews bigint,
pageVisits bigint,
time TimeStamp,
primary key(ID)
);
But if I add extra column time, if I want to insert each pageViews and pageVisits as new entry for specific time it creates huge number of entry in the table.
Is there any efficient way to do it?

I am assuming that you want to update pageViews and pageVisits everytime against a SessionID. In this case first insert will have say:
Session ID = 23R4E11, pageViews = 1, pageVisits = 1
Now if same user revisits same page, you will update existing row as:
Session ID = 23R4E11, pageViews = 2, pageVisits = 1
In this case to maintain all the updates, you can create one more table called as pageTrackerHistory and then write trigger which can insert entry in pageTrackerHistory table whenever update is made on pageTracker table.
By doing this your operational table pageTracker contains minimal rows and pageTrackerHistory table contains huge audit records.
Hope this will give you some direction. :-)

Related

Mysql Update query optimize for single table

I am using MySql database for my Project,
I have one table having 6 Millions records, Out of which I am updating around 5 Millions records, my table structure and query are as below.
Table
CREATE TABLE `temp` (
`ref_id_1` int(11) NOT NULL,
`ref_id_2` varchar(32) NOT NULL,
`dna_id` int(11) DEFAULT NULL,
`product_id` varchar(16) DEFAULT NULL,
PRIMARY KEY (`ref_id_1`,`ref_id_2`),
KEY `product_id` (`product_id`),
KEY `dna_id` (`dna_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Update Query
UPDATE temp SET dna_id = 8 WHERE product_id ='Dr_23' AND ref_id_1 = 4;
There are 5 Million records for Product Id Dr_23
Above query taking around 2 minutes to execute. I have 32 GB RAM and SSD Harddisk.
Does anyone know how to optimize this query

Database design to minimize requests to specific table data

I am working on a Spring-MVC application for which we are planning to create API's which can be consumed by external users into their own platform. To do so, the user must create an 'app' on our platform and then the accesstoken can be retrieved which can be used to access data by user, and make modifications to it.
Now, to do so, what I am doing is, I have created a table called as 'appdetails'. The user has to authorize the app, by passing in client-id, secret and I am returning an access-token, which can be used to directly work on data-set of the user who owns the app.
But doing a check everytime if the object being requested, belongs to the owner of app is proving more database calls for each request. How can I effectively minimize these calls. Here is how the database looks like. Please note, I am only putting relevant fields and I am using PostgreSQL. Explanation below image.
So, now when an user wants to access/POST a canvas object. I am receiving the canvas object and the access-token. But now I have to verify, if the groupid to which it has to be associated is the same as what the app-owner is admin for. More calls are required in Section, note. Here is the SQL code if anyone wants.
CREATE TABLE appDetails (
appid NUMERIC NOT NULL,
clientsecret VARCHAR NOT NULL,
clientid VARCHAR NOT NULL,
accesstoken VARCHAR NOT NULL,
CONSTRAINT appid PRIMARY KEY (appid)
);
CREATE TABLE person (
id INTEGER NOT NULL,
email VARCHAR NOT NULL,
appid NUMERIC NOT NULL,
CONSTRAINT id PRIMARY KEY (id)
);
CREATE TABLE groupaccount (
groupid INTEGER NOT NULL,
groupname VARCHAR NOT NULL,
id INTEGER NOT NULL,
CONSTRAINT groupid PRIMARY KEY (groupid)
);
CREATE TABLE groupmembers (
memberid INTEGER NOT NULL,
groupid INTEGER NOT NULL,
CONSTRAINT memberid PRIMARY KEY (memberid, groupid)
);
CREATE TABLE canvas (
canvasid VARCHAR NOT NULL,
groupid INTEGER NOT NULL,
memberid INTEGER NOT NULL,
CONSTRAINT canvasid PRIMARY KEY (canvasid)
);
CREATE TABLE section (
sectionid VARCHAR NOT NULL,
canvasid VARCHAR NOT NULL,
CONSTRAINT sectionid PRIMARY KEY (sectionid)
);
CREATE TABLE note (
noteid VARCHAR NOT NULL,
sectionid VARCHAR NOT NULL,
CONSTRAINT noteid PRIMARY KEY (noteid)
);
ALTER TABLE person ADD CONSTRAINT appDetails_person_fk
FOREIGN KEY (appid)
REFERENCES appDetails (appid)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;
ALTER TABLE groupaccount ADD CONSTRAINT person_groupaccount_fk
FOREIGN KEY (id)
REFERENCES person (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;
ALTER TABLE groupmembers ADD CONSTRAINT groupaccount_groupmembers_fk
FOREIGN KEY (groupid)
REFERENCES groupaccount (groupid)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;
ALTER TABLE canvas ADD CONSTRAINT groupaccount_canvas_fk
FOREIGN KEY (groupid)
REFERENCES groupaccount (groupid)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;
ALTER TABLE canvas ADD CONSTRAINT groupmembers_canvas_fk
FOREIGN KEY (memberid, groupid)
REFERENCES groupmembers (memberid, groupid)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;
ALTER TABLE section ADD CONSTRAINT canvas_section_fk
FOREIGN KEY (canvasid)
REFERENCES canvas (canvasid)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;
ALTER TABLE note ADD CONSTRAINT section_note_fk
FOREIGN KEY (sectionid)
REFERENCES section (sectionid)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;
Also, are there any technologies I can use to maintain Rate of consumption of API. The simplest I could think of was adding a counter in appdetails. I hope the question is clear, if not, kindly let me know. I will explain further.

#1467 - Failed to read auto-increment value from storage engine

I was trying to create a new object and this error appeared:
java.sql.sqlexception failed to read auto-increment value from storage engine
So I went to the phpMyAdmin to create the object there and the same showed up:
MySQL said: Documentation
1467 - Failed to read auto-increment value from storage engine
then I clicked on edit, and it was there:
INSERT INTO `reservation`.`room` (`idroom`, `number`, `floor`, `description`, `characteristics`, `cost`, `status`, `type`) VALUES (NULL, '114', '3', 'ss', 'ss', '550.00', 'Available', 'ss')
(idroom is supposed to be auto-incremented.)
I already read other posts where they say I have to put this:
ALTER TABLE `table_name` AUTO_INCREMENT = 1
but I have no idea where to put that. Is there a better solution?
Your INSERT statement is wrong. Since idroom is AUTO_INCREMENT; you must not include it in the column list on your insert command. Your insert statement should look like below. Notice that I have removed idroom column from insert column list and not passing NULL as well in value list.
INSERT INTO `reservation`.`room` (`number`, `floor`, `description`,
`characteristics`, `cost`, `status`, `type`)
VALUES ('114', '3', 'ss', 'ss', '550.00', 'Available', 'ss')
I also struggled with this problem and searched, and didn't find anything. Then the following worked for me; I guess it might work for your problem. Thx.
1st:
-delete (before backup)->all data from your database.
-try to run your Java program again, or any program you want.
If it fails then go to 2nd.
2nd:
- backup all data from your table
- delete table completely
- create table again; example shown below:
CREATE TABLE `users` (
`id` int(6) NOT NULL,
`f_name` varchar(30) NOT NULL,
`l_name` varchar(30) NOT NULL,
`address` varchar(50) DEFAULT NULL,
`phone_num` varchar(12) DEFAULT NULL,
`email` varchar(30) DEFAULT NULL
);
ALTER TABLE `users`
ADD PRIMARY KEY (`id`);
AUTO_INCREMENT for table `users`
ALTER TABLE `users`
MODIFY `id` int(6) NOT NULL AUTO_INCREMENT;

compare values from two tables

I have 2 tables. First one holds the total values of some shopping lists and the second table holds the products in that list. When a shopping list is done the total value is added into the total table together with some informations like the list number(nrList which is some kind of list id) and the number of products on that list nrProducts while the products go into the listproducts table.Lets say there are 3 products tomato,oranges and apples.They will all share the same nrList which,as mentioned before,is something like the list id.
First table totals:
CREATE TABLE IF NOT EXISTS `totals` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nrList` int(11) NOT NULL,
`nrProducts` int(11) DEFAULT NULL,
`total` double NOT NULL,
`data` date DEFAULT NULL,
`ora` time DEFAULT NULL,
`dataora` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`Operator` varchar(50) DEFAULT NULL,
`anulat` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
)
Second table listproducts:
CREATE TABLE IF NOT EXISTS `listproducts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nrList` int(11) DEFAULT NULL,
`product` varchar(50) DEFAULT NULL,
`quantity` double DEFAULT NULL,
`price` double DEFAULT NULL,
`data` date DEFAULT NULL,
`operator` varchar(50) NOT NULL,
`anulat` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
)
Now,i have two things i want to do,they are very similar.
Lets say i have a list with 3 products.In the totals table there will be a row with some info and with the total=10$ nrProducts=3 and nrList=1.In the listproducts table i will have 3 rows all having nrList=1 and each having price=3$,3$,4$.
Now,i want the check the following :
1.That if the value of nrProducts=3 then i have products for that list in the other table.
2.Check if the total in the first table is equal to the sum of the products in the second table.(quantity*price SUM)
I've done some stuff but i don't know what to do next.
I managed to get the number of products for each list from the second table by using this:
SELECT nrList,operator,COUNT(*) as count FROM listproducts GROUP BY nrList
But i don't know how to compare if the values are equal without doing two queries.
For the second thing again, I know how to get the sum but i don't know how to compare them without doing two separate queries.
SELECT SUM(price*quantity) FROM `listproducts` WHERE nrList='10' and operator like '%x%'
I can also do something like what i've done in the other select,this is not the issue.
The issue is that i don't know how to do the things i want in a single select instead of doing two and comparing them.I'm doing this in java so i can compare but i'd like to know if and how i can do this in a single query.
Thanks and sorry for the long post.
You can try something like this:
SELECT totals.nrList,
IF (totals.nrProducts = t.nrProductsActual, 'yes', 'no') AS matchNrProducts,
IF (totals.total = t.totalActual, 'yes', 'no') AS matchTotal
FROM totals INNER JOIN
(SELECT nrList,
COUNT(*) AS nrProductsActual,
SUM(quantity*price) AS totalActual
FROM listproducts
GROUP BY nrList) AS t ON totals.nrList = t.nrList

Mahout and custom table for data model

The documentation says that the table of ratings should look like this:
CREATE TABLE taste_preferences (
user_id BIGINT NOT NULL,
item_id BIGINT NOT NULL,
preference REAL NOT NULL,
PRIMARY KEY (user_id, item_id)
);
However, in my implementation table of ratings is as follows:
CREATE TABLE taste_preferences (
profile_id BIGINT NOT NULL,
event_id BIGINT NOT NULL,
status_id BIGINT NOT NULL,
PRIMARY KEY (user_id, item_id)
);
Where the grade is in the form status_id (go, no go, maybe I'll go).
The users table as follows:
CREATE TABLE user (
profile_id_1 BIGINT NOT NULL,
profile_id_2 BIGINT NOT NULL,
profile_id_3 BIGINT NOT NULL,
...
);
A user can have multiple profiles, I need to compare these data to users.
I need to write its own implementation of data model? Which way do I see, that would solve this problem? Thanks!
You don't have rating data here, in any form. So, you can't use ratings in recommendations. That's fine; you just have "boolean" data.
Or, you're saying you need to use status but I'm not clear how you want to use it.
You can certainly use your taste_preferences table. Just use MySQLBooleanPrefJDBCDataModel or similar. The user table is irrelevant.

Categories

Resources