DEV Community

Cover image for MySQL invisible columns and how to define it with Laravel and Doctrine
Matheus Lopes Santos
Matheus Lopes Santos

Posted on

5

MySQL invisible columns and how to define it with Laravel and Doctrine

Many developers don't know that MySQL now has support for invisible columns.

But what exactly is an invisible column?

When it arrives?

This attribute is available on MySQL since v8.0.23. According to the documentation:

An invisible column is normally hidden to queries, but can be accessed if explicitly referenced. Prior to MySQL 8.0.23, all columns are visible.

The syntax to create an invisible column is very simple:

create table employees (
    id int not null primary key auto_increment,
    name varchar(45) not null,
    ssn char(11) not null INVISIBLE
) ENGINE = InnoDB;
Enter fullscreen mode Exit fullscreen mode

Certainly, we can use DDL to switch a column between visible and invisible.

alter table employees alter column ssn set visible;
Enter fullscreen mode Exit fullscreen mode

Querying Data

Now, what happens if I execute select * from employees?

Querying all columns

Wow, where is my ssn column? Well, it's hidden 🙂! To retrieve that column, we need to explicitly specify it in our query:

Querying all columns with ssn

This is a good approach to exclude columns that don't need to be displayed in our query, such as those containing sensitive data.

Generating an invisible column with a Laravel Migration

If you wish to utilize this feature in a Laravel application, you can define your column as follows:

public function up(): void
{
    Schema::create('employees', function (Blueprint $table) {
        $table->id();
        $table->string('name', 45);
        $table->char('ssn', 11)->invisible();
    });
}
Enter fullscreen mode Exit fullscreen mode

Generating an invisible column with Doctrine

I've defined an entity called Employee with the following configuration

#[ORM\Entity]
#[ORM\Table(name: 'employees')]
class Employee
{
    #[ORM\Id]
    #[ORM\Column(type: 'integer')]
    #[ORM\GeneratedValue]
    private int | null $id;

    #[ORM\Column(type: 'string', length: 45)]
    private string $name;

    #[ORM\Column(columnDefinition: 'char(11) INVISIBLE')]
    private string $ssn;

    // The other methods of this entity
}
Enter fullscreen mode Exit fullscreen mode

Now, we have an additional security layer to prevent the exposure of our sensitive data!

That's all folks! See you on the next post 🙂 👍🏻

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (3)

Collapse
 
mauriciomueller profile image
Mauricio Mueller •

I believe this is also a good case for columns that use json or blob and you want to avoid from select all queries.

Collapse
 
mhraihan profile image
Mahmudul Haque Raihan •

if I want to query it from Laravel, how can I do it?

Collapse
 
devlopez profile image
Matheus Lopes Santos •

Hello, my friend. In this case, you should specify the field in the query. For example:

Employee::find(1, ['*', 'ssn']);
Enter fullscreen mode Exit fullscreen mode

🙂👍🏻

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more