MySQL - Table format for Click stats - mysql

I'm currently developing an URL shortening service. I want to allow users to see the stats for their URLs. How has to be the table.
First, it has to be the url ID, but then, how I can sort the clicks per day?

It really depends on what stats you want to be able to display. In the absolute most general case, you could have two columns: URL ID, and a timestamp of when someone used that URL, insert one row every time someone uses a URL through your service. This will generate a lot of rows, but you'll be able to get any statistics that you want.
I doubt that you need to-the-second statistics forever though, so I'd suggest setting up a scheduled job to run once a day or so, and "roll up" the statistics for the day into a second table. The second table could have 3 columns: URL ID, date, and number of clicks. Every day, go through the first table that contains every click, figure out how many clicks there were for each URL, and insert a "summary" row into the second table. Then delete all the individual click-rows from the first table.
Make sense?

Related

Best Approach for Bookmark Drill through in Power BI

I have a single session date(Day) chosen on the Dashboard home landing page ( page 1) via a dropdown date slicer. The chosen date is a selected date measure defined as:
SelectedDate = cALCULATE(max('Date'[DayTextLong]),FILTER('Date',SELECTEDVALUE('DateSelector'[DateId],MAX('DateSelector'[DateId])) = 'Date'[DateId]))
DateSelector table is a standalone disconnected date table that is a cutdown list of dates for dropdown to select a day for slicer. There is a connected DATE table in this data model.
On a scorecard on the Dashboard home landing page ( Page 1), for a daily amounts on sessions I have a bookmark( as cant drill through on scorecards), to a details table and on that page 2, I want to show the details of which customers. This is from a table that contains a request date and I need to filter the table by the selecteddate measure . How can I show a summarised table visual on Page 2 that filters from the Selected Date measure chose on Page 1?
I was trying to create a measure (Request Date Boo) that would set a measure to 1 or 0 for the relevant records to show from Session Requests table , which is just Session Name, Customer Name and request date , and then put a visual filter on for page 2 to say where Request Date Boo=1. This fails with an error around single value not being found as it telling me I need to aggregrate the request date.
I want to do this properly and wondered what is the normal way of showing a visual on page 2 of a Report , where you want to use a date and apply a filter to another table in the data model using that date.
Hope the question makes sense.
For what I understood, you have a filter on page 1, that must be kept when you navigate to page 2.
I've got three options:
Put the same date filter slicer on page 2 and allow it to sync with the others. In this way, when you navigate between pages that share synced slicers the filters will be kept. (this was also suggested by a comment)
Use the drillthrough functionality (docs here). This is a bit more complicated and does not create a "standard" page but it allows you to navigate to a detail page, based on a set of configured fields, when you navigate to this page you can also keep all the filters that were set before reaching this page. (This is a bit complicated to explain, the best thing you can do is to try it and see if it suits your needs)
Use What If parameters (docs here). I've never used for something like that, but if you can use them to choose a date you may use them to solve your problem.
All considered, probably the first solution is the easiest and most common solution for this kind of problem

Summing a ledger over long period of time. (reconciliation, snapshots, rolling sum?)

We are building a warehouse stock management system and have a stock movements table that records stock into, through and out of the system, for each product and each location it is stored. i.e.
10 units of Product A is received into Location A
10 units Product A are moved to Location B and removed from Location A.
1 unit is removed (sold) from Location B
... and so on.
This means that over to work out how much of each product is stored in each location we would;
"SELECT SUM('qty') FROM stock_movements GROUP BY location, product"
(we actually use Eloquent but I have used SQL for an example)
Over time, this will mean our stock movements table will grow to millions of rows and I am wondering the way to best manage this. The options I can think of:
Sum the rows as grouped above and accept it may get slow over time. Im not sure how many rows it will take before it actually starts to cause any performance issues. When requesting a whole inventory log via our API each row would have to be summed for every product, so this will compile to a fairly large calculation.
Create a snapshot of the summed rows every day/week/month etc. on a cron and then just add the sum of the most recent rows on the fly.
Create a separate table with a live stock level which is added to and subtracted with every stock movement. The stock movements table shows an entire history of all movements while the new table just shows the live amounts. We would use database transactions here to ensure they keep in sync.
Is there a defined and best practice way to handle this kind of thing already? Would love to hear your thoughts!
The good news is that your system is already where a lot of people say the database world should be moving: event sourcing. ES just stores every event against an object, in this case your location, and in order to get the current state you have to start with an empty object and replay all of that objects events.
Of course, this can be time-consuming, and your last two bullet points are the standard ways of dealing with it. First, you can create regular snapshots with the current-as-of-then totals for that location, and then when someone asks for the current-as-of-now totals you only need to replay events since the last snapshot. Second, you can have a separate table of current values, and whenever you insert a record into your event store you also update the current value. If they ever get out-of-sync, you can always start fresh and replay the entire event series again.
Both of these scenarios are typically managed through an intermediary queue service, like SQL's Service Broker, RabbitMQ, or Amazon's SQS: instead of inserting an event directly into your event store, you send the change into a queue and the code that processes the queue will update your snapshot.
Good luck!

MySQL query performance for paginating

Ok, so what is the best practice when it comes down to paginating in mysql. Let me make it more clear, let's say that a given time I have 2000 records and there are more being inserted. And I am displaying 25 at a time, I know I have to use limit to paginate through the records. But what am I supposed to do for the total count of my records? Do I count the records every time users click to request the next 25 records. Please, don't tell me the answer straight up but rather point me in the right direction. Thanks!
The simplest solution would be to just continue working with the result set normally as new records are inserted. Presumably, each page you display will use a query looking something like the following:
SELECT *
FROM yourTable
ORDER BY someCol
LIMIT 25
OFFSET 100
As the user pages back and forth, if new data were to come in it is possible that a page could change from what it was previously. From a logical point of view, this isn't so bad. For example, if you had an alphabetical list of products and a new product appeared, then the user would receive this information in a fairly nice way.
As for counting, your code can allow moving to the next page so long as data is there to support a new page being added. Having new records added might mean more pages required to cover the entire table, but it should not affect your logic used to determine when to stop allowing pages.
If your table has a date or timestamp column representing when a record was added, then you might actually be able to restrict the entire result set to a snapshot in time. In this case, you could prevent new data from entering over a given session.
3 sugggestions
1. Only refreshing the data grid, while clicking the next button via ajax (or) storing the count in session for the search parameters opted .
2. Using memcache which is advanced, can be shared across all the users. Generate a unique key based on the filter parameters and keep the count. So you won't hit the data base. When a new record, gets added then you need to clear the existing memcache key. This requires a memache to be running.
3. Create a indexing and if you hit the db for getting the count alone. There won't be much any impact on performance.

Design - Microsoft Access - Unique "Serial" Number

I am looking for some design techniques to achieve the following:
A 3-part serial number that is generated upon record entry. Format Example: 25-001-14
The number is used to track yearly records from various locations.
The first part states the location the record is associated with, this would be a user input during record creation.
The second part is the record number, I would like for this to be automatically generated, but needs to be sequential and separate for each location and needs to reset each year.
The third part is the two digit number for the year the record was created in. I would like this to be automatically generated if possible. Note: I am currently not concerned with when this cycles back around and I face redundant data issues.
I'm thinking I would like records to be stored in multiple tables that are separated by location, if this would help things!
Any ideas would be greatly welcomed.
I think I would use 3 key fields - one field each for location, record and year. The location and year fields would be created when you get the input to create new records. I would set up a query to find the last record number used by location and year and use that query to assign the new record number when you create a new record. The concatenation of the 3 fields would be the key you described.
With a key field for location, separate tables are not necessary unless that's useful for other reasons. I would probably use just one table - you can always filter the records by location anytime you need to.

Storing Invoices in MySQL

I wanted to get some advice on how to go about storing invoice data in a mysql database.
My first understanding would be to have two tables..
Invoices & Invoice_rows..
Invoices would hold FK to Client ID, invoice number, invoice date, paid or unpaid flag
Invoice_rows would hold all the items to invoice, FK to invoices, description, price, tax
Only thing is after the invoice is created it might need to be updated.. spelling mistake, extra item needed to be added etc. So for this is i will first need to query to get all of the rows, then I will need to execute multiple updates to all the rows every time a change is made.
Would storing all the rows as JSON in a text field for each individual invoice in the single invoices table work well or cause more of a problem? the fact that all rows will need to be updated regardless if there was only a change to one row upon save makes no difference just converting it to json and replacing the text field with the new JSON surely? The JSON wouldn't need to be searchable either as it's the client that will be searched and will list all of their invoices based upon their ID.
Any recommendation to make this efficient and easy to work with is most appreciated!
Just keep track of the changes in the front end and call your AJAX method when they're done. The method should take the invoice number and any updated rows including the PKs.
Do NOT store JSON in the database. That would be a truly awful thing. JSON is just a useful mechanism for transit and your choice of UI. It is not your data but a temporary transformation of it.