Author: way0utwest

  • A Dearth of Data

    Most of us feel that our data volumes are constantly growing. A lack of data isn’t something we worry about, at least not in production. In development, far too many people use sensitive data for developers, which certainly ensures there is enough data, but at a potential increase in liability if the data is mishandled.

    If we require developers to create their own data, often there is a problem with them not having enough, or certainly not a representative set that helps ensure the software meets enough of the specifications. This is a challenge, and while random data helps, it doesn’t always work well. This problem might be hard to solve with OLTP systems, but what about an AI or ML scenario, where we might need lots of data to train a system?

    Microsoft Research is working on ways to solve this problem. They presented a paper on Icebreaker, a technique that uses minimal data to train a model. I’m not sure I completely understand how this works, but the idea is to be able to work with very little training data and somehow still train the model. I’m guessing there is some ML inside of the process itself.

    There are all sorts of downsides with using existing data to train models. Sometimes we have inherent bias, or otherwise skewed data. Allowing a model to work with less data, and perhaps then working to change, or even skew, the data to meet our goals might help. Certainly this likely requires input and feedback from a data scientist of some sort, but that might be where we take advantage of the skills and knowledge of that staff.

    There will be more use of the AI/ML technologies in the future, if for no other reason than people are very interested in how this can improve the way that systems can help analyze data. Of course, techniques like this might help us deal with the challenges of doing so when we don’t have all the data we would like to have while building the model.

    Steve Jones

    Listen to the podcast at Libsyn, Stitcher or iTunes.

  • The DBA’s Twelve Days of Christmas

    On the first day of Christmas my new DBA sent to me
    A table with a primary key

    On the second day of Christmas my new DBA sent to me
    Two Foreign Keys, and
    A table with a primary key

    On the third day of Christmas my new DBA sent to me
    Three stored procs
    Two Foreign Keys, and
    A table with a primary key

    On the fourth day of Christmas my new DBA sent to me
    Four database roles
    Three stored procs
    Two Foreign Keys, and
    A table with a primary key

    On the fifth day of Christmas my new DBA sent to me
    Five execution plans
    Four database roles
    Three stored procs
    Two Foreign Keys, and
    A table with a primary key

    On the sixth day of Christmas my new DBA sent to me
    Six unnested views
    Five execution plans
    Four database roles
    Three stored procs
    Two Foreign Keys, and
    A table with a primary key

    On the seventh day of Christmas my new DBA sent to me
    Seven maintenance jobs
    Six unnested views
    Five execution plans
    Four database roles
    Three stored procs
    Two Foreign Keys, and
    A table with a primary key

    On the eighth day of Christmas my new DBA sent to me
    Eight tables to remove
    Seven maintenance jobs
    Six unnested views
    Five execution plans
    Four database roles
    Three stored procs
    Two Foreign Keys, and
    A table with a primary key

    On the ninth day of Christmas my new DBA sent to me
    Nine unit tests
    Eight tables to remove
    Seven maintenance jobs
    Six unnested views
    Five execution plans
    Four database roles
    Three stored procs
    Two Foreign Keys, and
    A table with a primary key

    On the 10th day of Christmas my new DBA sent to me
    Ten database containers
    Nine unit tests
    Eight tables to remove
    Seven maintenance jobs
    Six unnested views
    Five execution plans
    Four database roles
    Three stored procs
    Two Foreign Keys, and
    A table with a primary key

    On the 11th day of Christmas my new DBA sent to me
    Eleven Extended Events
    Ten database containers
    Nine unit tests
    Eight tables to remove
    Seven maintenance jobs
    Six unnested views
    Five execution plans
    Four database roles
    Three stored procs
    Two Foreign Keys, and
    A table with a primary key

    On the 12th day of Christmas my new DBA sent to me
    Twelve tickets already closed
    Eleven Extended Events
    Ten database containers
    Nine unit tests
    Eight tables to remove
    Seven maintenance jobs
    Six unnested views
    Five execution plans
    Four database roles
    Three stored procs
    Two Foreign Keys, and
    A table with a primary key

  • Double Check Your Math

    Performing calculations in our applications is important. In fact, if we do any sort of math, we really want to ensure that our results are what we expect. That seems obvious, but I’ve run into applications where the code deployed didn’t quite calculate things as expected. In fact, there are all sorts of cases where someone was using a type of rounding that didn’t work well. You can read about a number of stories in this article, some of which were very expensive.

    While much of the work of calculations is done in application software, there are powerful capabilities in a database platform that are useful, especially when working with more than a row of data. It seems that even when developers want to treat an RDBMS as a storage location, they still will manipulate data with SQL functions to get results from a query that are easier to work with in their application.

    Some of us might use FLOOR(), CEILING() , ROUND(), or other mathematical functions in our work. We should be sure this is what the actual specification calls for, and that we are performing the calculations correctly. After all, mathematics in computers are often not as precise as we’d like them to be, or perhaps, not as we’d expect them to be.

    This is one reason I think you should have database testing. Clients have had the wrong calculations in production, sometimes for years. When we make switches based on values, or we perform a calculation designed to somehow round or trim a number, we may do so incorrectly. I’ve seen incorrect discount rates, tax calculations, and more in production systems.

    Even if you don’t want to write tests for most of your database query code, you ought to at least ensure that any math calculations have some testing around them that documents the expected behavior with easy to use numbers. This might not prevent mistakes, but it does give you a way to explain what you expect to happen in the code, verify it works, and show the input and output to a client. Perhaps their set of eyes on your test and test data will prevent silly mistakes in your math algorithms.

    Steve Jones

     

  • Backwards Compatible Symmetric Keys in SQL Server 2017+

    I discovered recently that there was a change made in SQL Server 2017 to the way that symmetric key passphrases are hashed. There’s a KB article that notes the fix, but basically the passphrases used to be encrypted with SHA1. That’s cryptographically insecure, so the algorithm was updated to SHA2.

    This is a problem, and can cause some issues. I’ll show the issue and then how to get around it.

    No More Decryptions

    Let’s say I have a SQL Server 2016 instance and database. I run this code:

    CREATE SYMMETRIC KEY SalaryKey
    WITH ALGORITHM = AES_256
    , IDENTITY_VALUE = 'Salary Protection'
    , KEY_SOURCE = 'Protect this from hackers'
    ENCRYPTION BY PASSWORD = 'SomeReallyStr0ngP@ssword';
    GO
    OPEN SYMMETRIC KEY SalaryKey DECRYPTION BY PASSWORD  = 'SomeReallyStr0ngP@ssword'

    UPDATE dbo.Employees
      SET EncryptedSalary = ENCRYPTBYKEY(KEY_GUID('SalaryKey'), CAST(Salary AS VARCHAR(50)))
    GO

    I can easily decrypt this data:

    2019-12-05 12_12_54-SQLQuery2.sql - Plato_SQL2016.sandbox (PLATO_Steve (66))_ - Microsoft SQL Server

    Let’s now say I move this data to SQL Server 2017. It could be a restore, some ETL, replication, etc. In any case, I have the data there.

    Now, if I drop the symmetric key, or it doesn’t exist, I need to recreate it. These are supposed to be deterministic, which means I can run the code above and get the same key. I’ve done this on SQL 2014 and SQL 2016 databases, and I can decrypt data encrypted in another database if I use the same code to create the key. Let’s try this. I’ll run this code:

    CREATE SYMMETRIC KEY SalaryKey
    WITH ALGORITHM = AES_256
    , IDENTITY_VALUE = 'Salary Protection'
    , KEY_SOURCE = 'Protect this from hackers'
    ENCRYPTION BY PASSWORD = 'SomeReallyStr0ngP@ssword';
    GO
    OPEN SYMMETRIC KEY SalaryKey DECRYPTION BY PASSWORD  = 'SomeReallyStr0ngP@ssword'
    SELECT top 10
      e.EmpID
    , e.EmpSSN
    , e.Salary
    , CAST(DECRYPTBYKEY(e.EncryptedSalary) AS VARCHAR(50)) AS DecryptedSalary
    , e.EncryptedSalary
      FROM dbo.Employees AS e
    GO

    I get this:

    2019-12-05 12_15_24-SQLQuery1.sql - Plato_SQL2017.sandbox (PLATO_Steve (54))_ - Microsoft SQL Server

    Why do I get NULL? SQL Server can’t decrypt this data, so it returns a NULL This isn’t supposed to happen, but the hash change caused this.

    Let’s fix this.

    A Trace Flag

    The KB article linked above mentions that trace flag 4631 will fix this. Let’s try it. I’ll run this code:

    DROP SYMMETRIC KEY SalaryKey
    DBCC TRACEON( 4631)
    GO
    CREATE SYMMETRIC KEY SalaryKey
    WITH ALGORITHM = AES_256
    , IDENTITY_VALUE = 'Salary Protection'
    , KEY_SOURCE = 'Protect this from hackers'
    ENCRYPTION BY PASSWORD = 'SomeReallyStr0ngP@ssword';
    GO

    Now, let’s open the key and requery:

    2019-12-05 12_19_32-SQLQuery1.sql - Plato_SQL2017.sandbox (PLATO_Steve (54))_ - Microsoft SQL Server

    Hmm, this doesn’t seem right. With a little experimentation, I discovered the trace flag needs to be global, or it can be enabled instance wide. Let’s do that.

    DROP SYMMETRIC KEY SalaryKey
    DBCC TRACEOFF( 4631)
    DBCC TRACEON( 4631, -1)
    GO
    CREATE SYMMETRIC KEY SalaryKey
    WITH ALGORITHM = AES_256
    , IDENTITY_VALUE = 'Salary Protection'
    , KEY_SOURCE = 'Protect this from hackers'
    ENCRYPTION BY PASSWORD = 'SomeReallyStr0ngP@ssword';
    GO

    Now we query, and this works.

    2019-12-05 12_21_38-SQLQuery1.sql - Plato_SQL2017.sandbox (PLATO_Steve (54))_ - Microsoft SQL Server

    Most people don’t deal with column encryption, but if you do, be aware of this.