How can I store invite requests in DynamoDB? - sql

I'm trying to write an invite system for a project I'm working on. I plan on having a "give us your email address and we'll give you a beta invite when we're ready" type of thing. I'm trying to figure out how I can design a DynamoDB table so that I can query for the first x users who haven't already received an invite.
The table I'm thinking about creating would have something like the following columns:
email
date
fulfilled (boolean)
Can I do this with some combination of Hash keys, Range keys, and secondary indexes in DynamoDB? Or is this something that's better suited for a SQL database? The SQL query would be something like this:
SELECT email
FROM invite_request
WHERE fulfilled = 0
ORDER BY date
LIMIT 50;

Your best option here is to use the hash key as Fullfilled or Unfullfilled. That way you can use the query method which is much less expensive than scan. So your record would look like:
:Hash_key => Boolean , :Range_key => DateTime , Attributes => [email=>value]
Using this structure you can query all unfulfilled emails within a certain date range and limit the results. Hope this helps. If you want more access to the information for later you may want to look into SimpleDB as a better option, but if you're only using this for a single function Dynamo is a great way to go.

Related

Boolean Look up Tables - Bool Column or Simple Lookup?

We need a table to store requests for a copy of a contract, let's say contract_copy_requests.
The user either made a request, or did not. The field is unlikely to ever toggle.
Which of these column options is "correct":
profile_id, request date (and only write ids that made a request in here) OR
profile_id, has_requested_copy, updated_date
The latter is more complete and extensible, but the former is simpler and doesn't require either a nullable field or backfilling existing data with false for everyone since they haven't made the choice yet.
Is there any real reason to do #2? Btw, this is more of a generic question - I have had this use case come up about 3 times in the past month and I always lean toward #1 but wanted to validate it.
The first option is better.
It is smaller, and you lose no functionality: for example, it will be easy to get the users that didn't make a request:
... WHERE NOT EXISTS (SELECT 1 FROM contract_copy_requests AS ccr
WHERE ccr.request.id = /* column from the outside */)

Bigtable - read_rows and start_key

Is there a way to write the start_key for Bigtable? I was not able to find a clear documentation on what the syntax is for start_key.
Suppose I have a row key of {domain}_{timestamp} of user activity.
To filter the query to a specific domain I could use a filter (slower), or a start_key (faster).
I have been writing my start_key string as {domain}_, but what if we now have domain, user ID, and timestamp, and now I want to filter by any user but a specific time, can I use something like {domain}_*_{timestamp}?
You have to use a Filter with RegexStringComparator. You can also setStart({domain}_) for better performance. Unfortunately, that's going to pretty much going to do a scan on {domain}_ and filter on the server-side.
It might be faster to do a search with either a random user id, or if you need all users, to use Table.get(List<Get>) where each Get correspond to individual user.

Asterisk Realtime and External SIP table

I'm having spleepless night thanks to Asterisk Realtime.
I have some trouble understanding the documentation ( like http://www.voip-info.org/wiki/view/Asterisk+RealTime+Sip ). Too many tables, many parameters, fragmented informations, no exhaustive tutorial.
I have simply to auto-register some users from an external MySQL's table ( id, user, chatkey ).
Which are the columns i HAVE to set to get it work? If there where simply a user and password column, I would have matched them with my.user and my.chatkey, but now I'm very confused.
Is there any side effects using VIEWS instead table + triggers?
You have set ALL columns. Minimum set is something like type,username, host,name,nat,allow,disallow.
You can do it using mysql view from your current tables.But if you do so, you have use cache of realtime friends or organize contact update(update&store of all fields below&including ipaddr). Otherwise your setup will not able determine where your sip devices.
I don't understand your issues. Wiki is very clear. For sip auth you need only one table sip_buddies
and need put in /etc/asterisk/extconfig.conf
sipusers => mysql,general,sip_buddies
sippeers => mysql,general,sip_buddies
note, general - name of already setuped(in /etc/asterisk/res_mysql.conf) database connection.
From your question i see you not understanding asterisk internals, so i recommending you read Orely's book "Asterisk the future of telephony" or hire expert. Otherwise resulting application will be not scalable and probably will work strange.

How could i write this code in a more performant way?

In our app people have 1 or multiple projects. These projects have a start and an end date. People have a limited amount of available days.
Now we have a page that displays the availability of a given person on a week by week basis. It currently shows 18 weeks.
The way we currently calculate the available time for a given week is like this:
def days_available(query_date=Date.today)
days_engaged = projects.current.where("start_date < ? AND finish_date > ?", query_date, query_date).sum(:days_on_project)
available = days_total - hours_engaged
end
This means that to display the page descibed above the app will fire 18(!) queries into the database. We have pages that lists the availability of multiple people in a table. For these pages the amount of queries is quickly becomes staggering.
It is also quite slow.
How could we handle the availability retrieval in a more performant manner?
This is quite a common scenario when working with date ranges in an entity. Easy and fastest way is in SQL:
Join your events to a number generated date table (see generate days from date range) so that you have a row for each day a person or people are occupied. Once you have the data in this form it is simply a matter of grouping by the week date part of the date and counting the rows per grouping.
You can extend this to group by person for multiple person queries.
From a SQL point of view, I'd advise using a stored procedure and pass in your date/range requirement, you can then return a recordset for a user or possibly multiple users. This way your code just has to access db once.
You can then output recordset data in one go, by iterating through.
Hope this helps.
USE Stored procedure to fire your query to SQL to get data.
Pass paramerts in your case it is today's date to the SQl query.
Apply your conditions and Logic in the SQL Stored procedure , Using procedure is the goood and fastest way to retrieve data from the SQL , also it will prevent your code from the SQL injection too.
Call that SP from your Code as i dont know the Ruby on raisl I cant provide you steps about how to Call the Stored procedure from it.
After that the data fdetched as per you stored procedure will be available in Data table or something like that.
After getting the data you can perform all you need
Hope this helps
see what query is executed. further you may make comand explain to your query
explain select * from project where start_date < any_date and end_date> any_date2
you see the plan of query . Use this plan to optimized your query.
for example :
if you have index using field end_date replace a condition(end_date> any_date2 and start_date < any_date) . this step will using index if you have index on this field. But it step is db dependent . example is for nysql. if you want use index in mysql you must have using index condition on left part of where
There's not really enough information in your question to know exactly what you're trying to achieve here, e.g. the code snippet doesn't make use of the returned database query, so you could just remove it to make it faster. Perhaps this is just a bug in the code you posted?
Having said that, there are some techniques you should look into to implement your functionality.
I would take a look at using data warehouse techniques. I would think of your 'availability information' as a Fact table in a star schema, with 'Dates' and 'People' as Dimension tables.
You can then use queries to get stuff like - list of users for this projects for this week, and their availability.
Data warehousing has a whole bunch of resources you can tap into to help make this perform well, but there's also a lot of terminology that can be confusing, but for this type of 'I need to slice and dice my data across several sets of things (people and time)', Data Warehousing techniques can be quite powerful.
As I dont understand ruby on rails,from sql point of view i suggest you to write a stored procedure and return a dataset.And do the necessary table operations on the dataset from front end.It will reduce the unnecessary calls to DB.

What is the best way to do a wildcard search in sql server 2005?

So I have a stored procedure that accepts a product code like 1234567890. I want to facilitate a wildcard search option for those products. (i.e. 123456*) and have it return all those products that match. What is the best way to do this?
I have in the past used something like below:
SELECT #product_code = REPLACE(#product_code, '*', '%')
and then do a LIKE search on the product_code field, but i feel like it can be improved.
What your doing already is about the best you can do.
One optimization you might try is to ensure there's an index on the columns you're allowing this on. SQL Server will still need to do a full scan for the wildcard search, but it'll be only over the specific index rather than the full table.
As always, checking the query plan before and after any changes is a great idea.
A couple of random ideas
It depends, but you might like to consider:
Always look for a substring by default. e.g. if the user enters "1234", you search for:
WHERE product like "%1234%"
Allow users full control. i.e. simply take their input and pass it to the LIKE clause. This means that they can come up with their own custom searches. This will only be useful if your users are interested in learning.
WHERE product like #input