You’re building your data warehouse, and getting data into Redshift. You’ve got your ETL pipeline running, and presentation layer talking to the warehouse. Great.
But how to get access to that source data? Wouldn’t it be nice if that was close by too?
Join 35,000 others and follow Sean Hull on twitter @hullsean.
It may be you have 10-zillion rows of source data and don’t want or need to get all of that into Redshift and keep it there. But it would be nice to have access to it when you do.
Enter EXTERNAL tables, aka Spectrum. Now you can keep all your raw data in S3, an in place operational datastore of data before it’s been reworked and transformed. Use SQL to access it right where it sits.
Get all the advantages of lifecycle management in S3, and don’t pay all the redshift costs for data you don’t need all the time. Cool!
Let’s see how it works.
What is an EXTERNAL table?
Spectrum is Amazon’s rebranding of an old database technology called EXTERNAL TABLES. Back in the 90’s Oracle pioneered this work, allowing you to essentially map a CSV file, that sits outside the database proper. This means you can query all that juicy data sitting in flat files. Cool!
Athena allows you to query this stuff as a service, native to AWS. Spectrum allows you to create those external tables inside of Redshift.
Give Redshift permissions
Go into IAM and create a new role called “SeanSpectrumRole”. Assign the policy AmazonS3ReadOnlyPolicy. It looks like this:
If you’re using the dashboard you just pick the policy from the named list. However if you’re using CloudFormation, you’ll use the code above.
Now navigate your aws console to the Redshift dashboard, click clusters, and click the checkbox for your cluster. Probably there’s only one.
Now click the “Manage IAM Roles” button, and a dialog should popup.. Select the role you created earlier, SeanSpectrumRole. Then click “Apply Changes”.
The beauty of the AWS world is that servers themselves can have API permissions. In this case we gave the redshift cluster or server itself, access to S3 for our use below!
Create your spectrum schema
First you must create a spectrum schema. Here’s the syntax:
create external schema spectrum
from data catalog
Upload your data to S3 bucket
Here we create an s3 bucket called sean_spectrum, then upload one csv file named sean_numbers.txt.
$ aws s3api create-bucket --bucket sean_spectrum --region us-east-1
$ cd spectrum/
$ cat sean_numbers.txt
$ aws s3 cp sean_numbers.txt s3://sean_spectrum/
upload: ./sean_numbers.txt to s3://sean_spectrum/sean_numbers.txt
$ aws s3 ls s3://sean_spectrum/
2017-05-18 20:28:41 193 sean_numbers.txt
Note the names. The table name won’t turn out to be sean_numbers. It will be called sean_spectrum, and all files inside that directory will be queried. So make sure they have consistent formats!
Create & query your external table
Here’s how you create your external table. Note this is just a map to data. The data is still stored in S3. it is not brought into Redshift except to slice, dice & present.
mydb=# create external table spectrum_schema.sean_numbers(
row format delimited
fields terminated by ','
stored as textfile
Here’s how you query it:
mydb=# select * from spectrum_schema.sean_numbers order by id;
id | fname | lname | phone
12 | Scarlet | Witch | 23-35-47-555
15 | Wonder | Woman | 999-324-7878
21 | Dr. | Who | 44-22-55-77-88
32 | Quick | Silver | 22-33-77-99
35 | Bat | Man | 317-222-4777
75 | Marvel | Girl | 222-333-9595
99 | Storm | Cloud | 367-399-6767
Cool. We reordered data read from an S3 file!!!
Although you can’t create a view over a redshift table *AND* an S3 external table, you can query them together.
So for example if I have a table in redshift with addresses, I can join them together:
mydb=# select a.id, a.fname, a.lname, b.address from spectrum_schema.sean_numbers a, sean_addresses b
where a.id = b.id order by id;
id | fname | lname | phone | address
12 | Scarlet | Witch | 23-35-47-555 | 10 main st
15 | Wonder | Woman | 999-324-7878 | 25 center st
21 | Dr. | Who | 44-22-55-77-88 | 32 broadway
32 | Quick | Silver | 22-33-77-99 | 1 first st
35 | Bat | Man | 317-222-4777 | 99 west st
75 | Marvel | Girl | 222-333-9595 | 66 East Ave
99 | Storm | Cloud | 367-399-6767 | 50 North st